Base solution for your next web application

Activities of "mightyit"

Question

Product Version: 11.1 Product Type: MVC + Jquery Framework: .Net Core

I am trying to integrate with Elsa in our solution. However I have come across a few problems and cannot seem to make it work. I believe this is due to the fact that the guide and demo project are outdated. The guide and demo project are for .Net 5 and the Elsa packages are version 2.0.0.159.

I cannot due to various package dependencies use the Elsa packages of that version in our solution. The earliest version I am able to use is 2.5.0. Elsa has made some changes to their solution and packages since 2.0.0.159 most notably to the Webhook Definitions List class which is required according to the documentation to register Elsa controllers in the Asp Net Zero dependency injection system.

The class has now been moved to a different package: Elsa.Webhooks.Api I made the adjustment to the Initialize method in the WebMvcModule

This is how the workflow page looks

and there are errors in the console

This is what my Program.cs looks like

It seems like either the controllers and razor pages aren't being registered correctly due to some difference between the demo/documentation elsa package versions and the version I am trying to use, or the embedded static files are not being loaded correctly.

Has anyone managed to get the elsa integration working on .Net 6? If so how were you able to get it to work?

Any help would be appreciated.

Product Version: 11.2.0 Product Type: MVC Product Type: .Net Core

ABP Framework Version: 7.3.0

Hi

We are noticing extremely long request times with the TokenAuth/Authenticate method in our production environment. Authenticate requests are taking 65 seconds to complete with clients using the API.

However when I run a authenticate request via postman it only takes 1.6 seconds. We have other methods exposed to our API which are nowhere near as slow as the authenticate these take under a second to complete.

Our resource usage on the app service is extremely low when these requests take so long to complete so its not a resource bottleneck that is causing the issue.

Any help in this regard would be greatly appreciated.

Hi

I receive a 404 not found error whenever I try to access hyperlinks to Github issues / code samples / documentation from the AspNetZero support forums. Please advise.

I checked the documentation at https://aspnetboilerplate.com/Pages/Documents/Swagger-UI-Integration

Swagger UI does not render the authorization dialog for bearer token authentication. This seems to be due to abp-specific javascript contained in wwwroot/swagger/ui/index.html, for the onload event, not returning null, in stead of the proper markup for the authorizebtn component.

 configObject.plugins = [
                function (system) {
                    return {
                        components: {
                            authorizeBtn: function () {
                                return null; // <-- Returning null in stead of authorize button markup
                            }
                        }
                    }
                }
            ];

Here is the OAS3 markup that is generated from my API during runtime (shortened)

{
    "openapi": "3.0.1",
    "info": {
        "title": "MyDemo Host API v1",
        "version": "v1"
    },
    "paths": {
        "/api/services/app/Tenant/CreateTenant": {
            "post": {
                "tags": [
                    "Tenant"
                ],
                "operationId": "ApiServicesAppTenantCreatetenantPost",
                "requestBody": {
                    "content": {
                        "application/json-patch+json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/components/schemas/CreateTenantInput"
                                    }
                                ]
                            }
                        },
                        "application/json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/components/schemas/CreateTenantInput"
                                    }
                                ]
                            }
                        },
                        "text/json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/components/schemas/CreateTenantInput"
                                    }
                                ]
                            }
                        },
                        "application/*+json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/components/schemas/CreateTenantInput"
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "$ref": "#/components/schemas/SwaggerDocResponseWrapper"
                                }
                            },
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SwaggerDocResponseWrapper"
                                }
                            },
                            "text/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SwaggerDocResponseWrapper"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearer": []
                    }
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "CreateTenantInput": {
                "required": [
                    "adminEmailAddress",
                    "name",
                    "tenancyName"
                ],
                "type": "object",
                "properties": {
                    "tenancyName": {
                        "maxLength": 64,
                        "minLength": 0,
                        "pattern": "^[a-zA-Z][a-zA-Z0-9_-]{1,}$",
                        "type": "string"
                    },
                    "name": {
                        "maxLength": 128,
                        "minLength": 0,
                        "type": "string"
                    },
                    "adminEmailAddress": {
                        "maxLength": 256,
                        "minLength": 0,
                        "type": "string",
                        "format": "email"
                    },
                    "adminPassword": {
                        "maxLength": 128,
                        "minLength": 0,
                        "type": "string",
                        "nullable": true
                    },
                    "connectionString": {
                        "maxLength": 1024,
                        "type": "string",
                        "nullable": true
                    },
                    "shouldChangePasswordOnNextLogin": {
                        "type": "boolean"
                    },
                    "sendActivationEmail": {
                        "type": "boolean"
                    },
                    "editionId": {
                        "type": "integer",
                        "format": "int32",
                        "nullable": true
                    },
                    "isActive": {
                        "type": "boolean"
                    },
                    "subscriptionEndDateUtc": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "isInTrialPeriod": {
                        "type": "boolean"
                    },
                    "onSellingPartnerId": {
                        "type": "integer",
                        "format": "int32",
                        "nullable": true
                    },
                    "onSellingPartner": {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/OnSellingPartnerDto"
                            }
                        ],
                        "nullable": true
                    },
                    "contactPersonFirstName": {
                        "maxLength": 32,
                        "type": "string",
                        "nullable": true
                    },
                    "contactPersonLastName": {
                        "maxLength": 32,
                        "type": "string",
                        "nullable": true
                    },
                    "contactNumber": {
                        "maxLength": 24,
                        "type": "string",
                        "nullable": true
                    },
                    "contactEmail": {
                        "maxLength": 256,
                        "type": "string",
                        "nullable": true
                    },
                    "taxNumber": {
                        "maxLength": 24,
                        "type": "string",
                        "nullable": true
                    },
                    "registeredName": {
                        "maxLength": 256,
                        "type": "string",
                        "nullable": true
                    },
                    "tenantBillingAddress": {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/TenantBillingAddressInput"
                            }
                        ],
                        "nullable": true
                    }
                },
                "additionalProperties": false
            },
            "ValidationError": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "nullable": true
                    },
                    "members": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "nullable": true
                    }
                },
                "additionalProperties": false
            },
            "SwaggerDocResponseWrapper": {
                "type": "object",
                "properties": {
                    "result": {
                        "type": "string",
                        "nullable": true
                    },
                    "targetUrl": {
                        "type": "string",
                        "nullable": true
                    },
                    "success": {
                        "type": "boolean"
                    },
                    "error": {
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/ResponseError"
                            }
                        ],
                        "nullable": true
                    },
                    "unauthorizedRequest": {
                        "type": "boolean"
                    },
                    "__Abp": {
                        "type": "boolean"
                    }
                },
                "additionalProperties": false
            },
            "OnSellingPartnerDto": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "nullable": true
                    },
                    "isActive": {
                        "type": "boolean"
                    },
                    "registeredName": {
                        "type": "string",
                        "nullable": true
                    },
                    "taxNumber": {
                        "type": "string",
                        "nullable": true
                    },
                    "contactNumber": {
                        "type": "string",
                        "nullable": true
                    },
                    "contactPersonFirstName": {
                        "type": "string",
                        "nullable": true
                    },
                    "contactPersonLastName": {
                        "type": "string",
                        "nullable": true
                    },
                    "contactEmail": {
                        "type": "string",
                        "nullable": true
                    },
                    "id": {
                        "type": "integer",
                        "format": "int32"
                    }
                },
                "additionalProperties": false
            },
            "TenantBillingAddressInput": {
                "type": "object",
                "properties": {
                    "streetAddress": {
                        "maxLength": 256,
                        "minLength": 0,
                        "type": "string",
                        "nullable": true
                    },
                    "region": {
                        "maxLength": 64,
                        "minLength": 0,
                        "type": "string",
                        "nullable": true
                    },
                    "city": {
                        "maxLength": 64,
                        "minLength": 0,
                        "type": "string",
                        "nullable": true
                    },
                    "countryId": {
                        "type": "integer",
                        "format": "int32",
                        "nullable": true
                    },
                    "regionCode": {
                        "maxLength": 6,
                        "minLength": 0,
                        "type": "string",
                        "nullable": true
                    }
                },
                "additionalProperties": false
            },
            "ResponseError": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "integer",
                        "format": "int32"
                    },
                    "message": {
                        "type": "string",
                        "nullable": true
                    },
                    "details": {
                        "type": "string",
                        "nullable": true
                    },
                    "validationErrors": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        },
                        "nullable": true
                    }
                },
                "additionalProperties": false
            }
        },
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "description": "Specify the authorization token.",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            }
        }
    },
    "security": [
        {}
    ]
}

This renders correctly when running it through editor.swagger.io (with "Authorize" button and bearer authentication dialog working correctly).

However, it renders incorrectly on my ASPNetZero / ABP solution....

The following version and Nuget package information applies

  • AspNetZero Core MVC & JQuery v10.3.0 (.Net 5)
  • Abp (6.2.0)
  • Swashbuckle.AspNetCore (5.6.3) & Swashbuckle.AspNetCore.NewtonSoft (6.1.4)
  • .Net 5

I am writing a utility that allows a host user to do batch loading of data on behalf of a tenant, via our API. For this, I have generated a .Net Core 2.2 client with NSwag, based on the generated swagger docs. This of course means that we use TokenAuth for authentication.

I am getting stuck with impersonation though. I am able to get an impersonation token, but get stuck when I want to authenticate as the impersonated user & tenant.

Here is my code through which I invoke the generated TokenAuth client:

// Get the impersonation token...
var accountClient = new AccountClient(_baseUri, _httpClient);
var impersonationToken = (await accountClient.ImpersonateAsync(new ImpersonateInput
{
    TenantId = selectedTenantId,
    UserId = selectedUserId,
})).ImpersonationToken;
            
var tokenAuthClient = new TokenAuthClient(_baseUri, _httpClient);            
var impersonatedAccessToken =
    (await tokenAuthClient.ImpersonatedAuthenticateAsync(impersonationToken)).AccessToken; // <== This call is generating Http Error 500

In my Web.Core project, the ImpersonatedAuthenticate method is being called on TokenAuthController as follows:

[HttpPost]
public async Task<ImpersonatedAuthenticateResultModel> ImpersonatedAuthenticate(string impersonationToken)
{
    var result = await _impersonationManager.GetImpersonatedUserAndIdentity(impersonationToken); <== This line is generating the exception
    var accessToken = CreateAccessToken(await CreateJwtClaims(result.Identity, result.User));

    return new ImpersonatedAuthenticateResultModel
    {
        AccessToken = accessToken,
        EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
        ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
    };
}

Here is the exception I am getting:

Further details:

  • I'm using the AspNetCore + JQuery version of the framework
  • Abp.AspNetZeroCore 1.2.2
  • Abp.ZeroCore 4.4.0

I have created two OpenApi specifications (HostApiv1 and TenantApiv1) as follows in Startup.cs:

services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("HostApiv1", new Info { Title = "Host API v1", Version = "v1" });
    options.SwaggerDoc("TenantApiv1", new Info { Title = "Tenant API v1", Version = "v1" });

    options.DocInclusionPredicate((docName, description) => true);
    options.IgnoreObsoleteActions();
    options.IgnoreObsoleteProperties();
    options.OrderActionsBy((apiDesc) => $"{apiDesc.RelativePath}");
    options.DescribeAllEnumsAsStrings();
});
app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint(_appConfiguration["App:HostApiSwaggerEndPoint"], "Host API v1");
    options.SwaggerEndpoint(_appConfiguration["App:TenantApiSwaggerEndPoint"], "Tenant API v1");
    //...
});

However, when I decorate my AppService classes with [ApiExplorerSettings(GroupName = "HostApiv1")], the grouping is ignored and the tag (AppService controller), along with all of its operations (actions / methods), still appear under both documents.

Please advise.

Let's say we have a table called "MyEntities" in SQL Server with the corresponding IEntity class "MyEntity"; The class "MyEntity" is decorated with the [TableName("MyEntities")] attribute.

When using IDapperRepository<MyEntity> to query the database, it unfortunately resolves to the singular form for the table name, in stead of the TableName attribute specified.

Is there any way to correct this behaviour?

[Table("PersonRecords")]
public class PersonRecord : FullAuditedEntity<Guid>, IMayHaveTenant
{
          //More attributes
}
// Meanwhile, in a client class somewhere....
public class Consumer 
{

    private readonly IDapperRepository<PersonRecord, Guid> _personRecordDapperRepository;

    public Consumer(
        IDapperRepository<PersonRecord, Guid> personRecordDapperRepository)
    {
        _personRecordDapperRepository = personRecordDapperRepository;
    }

    public void DoSomething()
    {
            _personRecordDapperRepository.GetAll(); // <== Generates exception
    }
}

Here is the exception:

System.Data.SqlClient.SqlException HResult=0x80131904 Message=Invalid object name 'PersonRecord'. Source=Core .Net SqlClient Data Provider StackTrace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior) at Dapper.SqlMapper.ExecuteReaderWithFlagsFallback(IDbCommand cmd, Boolean wasClosed, CommandBehavior behavior) in C:\projects\dapper\Dapper\SqlMapper.cs:line 1064 at Dapper.SqlMapper.<QueryImpl>d__1381.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.cs:line 1081 at System.Collections.Generic.List1.AddEnumerable(IEnumerable1 enumerable) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable1 commandTimeout, Nullable1 commandType) in C:\projects\dapper\Dapper\SqlMapper.cs:line 723 at DapperExtensions.DapperImplementor.GetList[T](DbConnection connection, IClassMapper classMap, IPredicate predicate, IList1 sort, DbTransaction transaction, Nullable1 commandTimeout, Boolean buffered) at DapperExtensions.DapperImplementor.GetList[T](DbConnection connection, Object predicate, IList1 sort, DbTransaction transaction, Nullable1 commandTimeout, Boolean buffered) at DapperExtensions.DapperExtensions.GetList[T](DbConnection connection, Object predicate, IList1 sort, DbTransaction transaction, Nullable1 commandTimeout, Boolean buffered) at Abp.Dapper.Repositories.DapperRepositoryBase2.GetAll() at Castle.Proxies.Invocations.DapperRepositoryBase2_GetAll.InvokeMethodOnTarget() at Castle.DynamicProxy.AbstractInvocation.Proceed() at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) at Castle.DynamicProxy.AbstractInvocation.Proceed() at Castle.Proxies.DapperEfRepositoryBase3Proxy.GetAll()

The generic repository for an entity with the [Audited] decoration will cause an exception due to DbContext being disposed prematurely. I am using Hangfire.

 [Audited]
    public class MyAuditedEntity: FullAuditedEntity<Guid>
    {
        public virtual string Name { get; set; }
        public virtual string Description { get; set; }
    }
public class TroubleshootingBackgroundJob : BackgroundJob<TroubleshootingBackgroundJobArgs>, TransientDependency
{
    private readonly IRepository<MyAuditedEntity, Guid> _repository;

    public TroubleshootingBackgroundJob(IRepository<MyAuditedEntity, Guid> repository)
    {
        _repository = repository;
    }

    [UnitOfWork]
    public override void Execute(TroubleshootingBackgroundJobArgs args)
    {
        repository.GetAll().ToList(); // <== Generates the exception
    }
}

Exception details:

System.ObjectDisposedException HResult=0x80131622 Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. ObjectDisposed_ObjectName_Name Source=Microsoft.EntityFrameworkCore StackTrace: at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed() at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_Model() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityType() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityQueryable() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.System.Linq.IQueryable.get_Provider() at System.Linq.Queryable.Where[TSource](IQueryable1 source, Expression`1 predicate)

Am I missing something or is this a bug?

UPDATE It seems the problem is with all types of FullAuditedEntity, not the [Audited] decoration...

I am working on a feature which deals with bulk dataprocessing and of which the performance and scalability aspects is critical.

During the execution of the operation I have to insert thousands of records to the database via EfCore. I am hoping to do this with a single trip to the database through a BulkInsert extension method on IRepository<T>.

I have read the following thread which creates the impression that this functionality has been incorporated into the Abp framework, but I am having trouble surfacing it https://github.com/aspnetboilerplate/aspnetboilerplate/issues/3476

I have also noticed that there is a Nuget package Abp.EntityFrameworkCore.BulkExtensions, but this was last updated in 2017.

What is currently the recommended avenues to perform bulk database operations in AspNetZero / EfCore?

Hi

I am getting the following error during run-time when trying to invoke a method on ***AppService, which is contained in a separate, well-contained module that is separate from my generated solution modules.

The module consists of several sub-modules, with proper dependencies set up between them

I have also done the following in terms of module dependencies:

  • Added a module dependency from my module core to AbpZeroCommonModule
  • Added the required module dependencies from my base solution Web.Core solution to the custom modules. (All app services from the module runs successfully, except this specific one)

Can't create component '***AppService' as it has dependencies to be satisfied.

'***AppService' is waiting for the following dependencies:

  • Service 'Abp.Domain.Repositories.IRepository`2[[Abp.Authorization.Users.AbpUserBase, Abp.Zero.Common, Version=4.4.0.0, Culture=neutral, PublicKeyToken=null],[System.Int64, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' which was not registered.

Castle.MicroKernel.Handlers.HandlerException: Can't create component '***AppService' as it has dependencies to be satisfied.

'***AppService' is waiting for the following dependencies:

  • Service 'Abp.Domain.Repositories.IRepository`2[[Abp.Authorization.Users.AbpUserBase, Abp.Zero.Common, Version=4.4.0.0, Culture=neutral, PublicKeyToken=null],[System.Int64, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' which was not registered.

Here is the redacted code for the affected applicationservice:

Please help - what am I missing here?

Showing 1 to 10 of 17 entries