Open Closed

Mvc.Authorization.AbpAuthorizationFilter - UnitOfWork error #10816


0
coforgetech created

What is your product version? 10.3 What is your product type (Angular or MVC)? Angular What is product framework type (.net framework or .net core)? .Net Core Which theme are you using? Default What is ABP Framework version? 6.3

Hi team, We’re getting the below error when we’re visiting the pages and it occurs intermittently. We neither customize the authentication nor UnitOfWork or wrote any wrapper.

We are only using DI to get repository or services.

Error with Stack Trace:

ERROR 2022-01-14 12:49:34,865 [53 ] Mvc.Authorization.AbpAuthorizationFilter - System.ArgumentNullException: Value cannot be null. (Parameter 'unitOfWork') at Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContextAsync[TDbContext](IActiveUnitOfWork unitOfWork, Nullable1 multiTenancySide, String name) at Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider1.GetDbContextAsync(Nullable1 multiTenancySide) at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetContextAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetDbQueryTableAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetQueryableAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetAllIncludingAsync(Expression1[] propertySelectors) at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetAllAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.FirstOrDefaultAsync(TPrimaryKey id) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.Users.AbpUserManager2.<>c__DisplayClass88_0.<<GetUserPermissionCacheItemAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Abp.Runtime.Caching.TypedCacheWrapper2.<>c__DisplayClass18_0.<<GetAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Abp.Runtime.Caching.AbpCacheBase2.GetAsync(TKey key, Func2 factory) at Abp.Runtime.Caching.TypedCacheWrapper2.GetAsync(TKey key, Func2 factory) at Abp.Authorization.Users.AbpUserManager2.GetUserPermissionCacheItemAsync(Int64 userId) at Abp.Authorization.Users.AbpUserManager2.IsGrantedAsync(Int64 userId, Permission permission) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.Users.AbpUserManager2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionChecker2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionChecker2.IsGrantedAsync(String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionCheckerExtensions.IsGrantedAsync(IPermissionChecker permissionChecker, Boolean requiresAll, String[] permissionNames) at Abp.Authorization.PermissionCheckerExtensions.AuthorizeAsync(IPermissionChecker permissionChecker, Boolean requireAll, String[] permissionNames) at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(IEnumerable1 authorizeAttributes) at Abp.Authorization.AuthorizationHelper.CheckPermissionsAsync(MethodInfo methodInfo, Type type) at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(MethodInfo methodInfo, Type type) at Abp.AspNetCore.Mvc.Authorization.AbpAuthorizationFilter.OnAuthorizationAsync(AuthorizationFilterContext context) System.ArgumentNullException: Value cannot be null. (Parameter 'unitOfWork') at Abp.EntityFrameworkCore.Uow.UnitOfWorkExtensions.GetDbContextAsync[TDbContext](IActiveUnitOfWork unitOfWork, Nullable1 multiTenancySide, String name) at Abp.EntityFrameworkCore.Uow.UnitOfWorkDbContextProvider1.GetDbContextAsync(Nullable1 multiTenancySide) at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetContextAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetDbQueryTableAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetQueryableAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetAllIncludingAsync(Expression1[] propertySelectors) at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.GetAllAsync() at Abp.EntityFrameworkCore.Repositories.EfCoreRepositoryBase3.FirstOrDefaultAsync(TPrimaryKey id) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.Users.AbpUserManager2.<>c__DisplayClass88_0.<<GetUserPermissionCacheItemAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Abp.Runtime.Caching.TypedCacheWrapper2.<>c__DisplayClass18_0.<<GetAsync>b__0>d.MoveNext() --- End of stack trace from previous location --- at Abp.Runtime.Caching.AbpCacheBase2.GetAsync(TKey key, Func2 factory) at Abp.Runtime.Caching.TypedCacheWrapper2.GetAsync(TKey key, Func2 factory) at Abp.Authorization.Users.AbpUserManager2.GetUserPermissionCacheItemAsync(Int64 userId) at Abp.Authorization.Users.AbpUserManager2.IsGrantedAsync(Int64 userId, Permission permission) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.Users.AbpUserManager2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionChecker2.IsGrantedAsync(Int64 userId, String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionChecker2.IsGrantedAsync(String permissionName) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) at Abp.Authorization.PermissionCheckerExtensions.IsGrantedAsync(IPermissionChecker permissionChecker, Boolean requiresAll, String[] permissionNames) at Abp.Authorization.PermissionCheckerExtensions.AuthorizeAsync(IPermissionChecker permissionChecker, Boolean requireAll, String[] permissionNames) at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(IEnumerable1 authorizeAttributes) at Abp.Authorization.AuthorizationHelper.CheckPermissionsAsync(MethodInfo methodInfo, Type type) at Abp.Authorization.AuthorizationHelper.AuthorizeAsync(MethodInfo methodInfo, Type type) at Abp.AspNetCore.Mvc.Authorization.AbpAuthorizationFilter.OnAuthorizationAsync(AuthorizationFilterContext context)


13 Answer(s)
  • 0
    ismcagdas created
    Support Team

    Hi @coforgetech

    Does this happen in a specific page ? If so, could you share related app service code with us ?

    Thanks,

  • 0
    coforgetech created

    This issue is intermittent and is occurring on some pages. Below the code snippet from one of the page where issue is found.

    [AbpAuthorize(AppPermissions.Services_CS_TW)]

    public class TWAppService: DashboardAppServiceBase, ITWAppService
    {
        private readonly IFFOrgRepository _ffOrgRepository;
        public TWAppService(IFFOrgRepository FFOrgRepository)
        {
            _ffOrgRepository = FFOrgRepository;
        }
    
        [HttpGet]
        public async Task&lt;WkObject&gt; GetViewWk()
        {
            return await _ffOrgRepository.GetViewWk();
        }
    
  • 0
    coforgetech created

    Support team. Please suggest.

  • 0
    ismcagdas created
    Support Team

    Hi,

    Could you also share _ffOrgRepository.GetViewWk() method source code ? AppService code seems fine.

  • 0
    coforgetech created

    Please find source code of inner service which ABP team ask for UnitOfWork.

    Public class TWAppService: ITWAppService { private readonly ObjectPool<ApiDC> _objectPool; private readonly IConfigurationRoot _configuration; private readonly FFConfig _fFConfig; private readonly IDSRepository _dsRepository; private readonly ILogger _logger;

    public TWAppService ( IAppConfigurationAccessor appConfigurationAccessor, IDSRepository dsRepository, ObjectPool<ApiDC> objectPool, ILogger logger) { _configuration = appConfigurationAccessor.Configuration; _fFConfig = new FFConfig(); _configuration.GetSection(FFConfig.FFConfig).Bind(_FFConfig); _dsRepository = dsRepository; _objectPool = objectPool; _logger = logger; }

    public async Task<WKObject> GetViewWk() { var apiContext = _objectPool.Get(); var ds = _dsRepository.GetDataSource(DefaultSource.Ff.GetHashCode()); var ViewUrl = ds.BaseUrl + _FFConfig.ViewWiki; var data = await apiContext.GetData(ViewUrl, ds); var obj = JsonConvert.DeserializeObject<WKObject>(data); return obj; } }

  • 0
    ismcagdas created
    Support Team

    Hi @coforgetech

    Your code seems fine to me. Is it possible to access your project's source code somehow ? We can reproduce the problem and offer a fix to you.

  • 0
    shedspotter created

    Hi @ismcagdas , I have also encounterd the same issue but when I am running the hangfire schedule job at that time I am getting this issue

    Thanks

  • 0
    ismcagdas created
    Support Team

    Hi @shedspotter

    Could you share your Job's code with me ?

  • 0
    rickfrankel created

    @ismcagdas Is there any update on this one? I've seen this multiple times as well. We can reproduce it every time on a particular AppService. This AppService was working fine in version 10, but upgrading to 11.2 and I've got this error happening randomly as well.

  • 0
    rickfrankel created

    My AppService is a little different here.

    I do a GetAll on a simple IRepository.

    I take the result and call result.Select(_ => new OutputDto { Id = _.Id FieldSomethingElse = anotherRepository.FirstOrDefault(.AnotherFieldId).MyProp });

    The call to _anotherRepository is failing due to it loosing the UnitOfWork for some reason. No Hangfire jobs or anything else like this should be causing it as it is reproducible everytime on this AppService.

  • 0
    rickfrankel created

    At a guess it is very likely related to this comment as well. https://github.com/aspnetboilerplate/aspnetboilerplate/issues/6274

  • 0
    rickfrankel created

    Ok. Perhaps not related to that issue. I changed the AddApp() call to be false for the RemoveConventionalInterceptors and it still fails.

    PS: When trying to debug AspBoilerplate I get this now and cannot load symbols. Skipping symbol server "https://symbols.nuget.org/download/symbols". This server requires a PDB Checksum, which is not present in the binary being debugged https://symbols.nuget.org/download/symbols: Symbols not found on symbol server.

    I'm still trying to find the cause, but it definitely looks like the unit of work doesn't get created for some reason. Or the one it was using is closed before the repository has used it.

  • 0
    rickfrankel created

    I think I've reproduced this in a slightly different way with a different exception.

    I downloaded a completely clean version of 11.2.

    And adjusted the GetUsers API call in the following way.

        [HttpPost]
        public async Task&lt;PagedResultDto&lt;UserListDto&gt;> GetUsers(GetUsersInput input)
        {
            var query = GetUsersFilteredQuery(input);
    
            var userCount = await query.CountAsync();
    
            var users = await query
                .OrderBy(input.Sorting)
                .PageBy(input)
                .ToListAsync();
    
            var userListDtos = ObjectMapper.Map&lt;List&lt;UserListDto&gt;>(users);
            await FillRoleNames(userListDtos);
    
            var roles = _userRoleRepository.GetAll();
    
            var test = await roles.Select(_ => new
            {
                Fred = _roleRepository.FirstOrDefault(_.RoleId)
            }).ToListAsync();
    
    
            return new PagedResultDto&lt;UserListDto&gt;(
                userCount,
                userListDtos
            );
        }
    

    When you now run the vanilla solution and go to the users screen in the admin you get the following exception. It is a slightly different exception but that could be related to me using MySQL in my actual project, but in the vanilla solution I tried using MSSQL.

    I also note an exception logged from the auditing (which I think is swallowed anyway) due to me running locally and the IP address being ::1

    Either way I can't see why the above code shouldn't work correctly and from what I can tell it did in previous versions.

    Thanks

    ERROR 2022-06-23 17:11:17,525 [37 ] Mvc.ExceptionHandling.AbpExceptionFilter - There is already an open DataReader associated with this Connection which must be closed first. System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first. at Microsoft.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) at Microsoft.Data.SqlClient.SqlCommand.ValidateCommand(Boolean isAsync, String method) at Microsoft.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String method) at Microsoft.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.InitializeReader(Enumerator enumerator) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.Enumerator.MoveNext() at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable1 source, Boolean& found) at lambda_method2167(Closure , QueryContext ) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable1 source, Expression1 predicate) at Abp.Domain.Repositories.AbpRepositoryBase2.FirstOrDefault(TPrimaryKey id) at lambda_method2163(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator ) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.AsyncEnumerator.MoveNextAsync() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken) at Inbound.Authorization.Users.UserAppService.GetUsers(GetUsersInput input) in C:\Source\Inbound-v11-2\aspnet-core\src\Inbound.Application\Authorization\Users\UserAppService.cs:line 124 at lambda_method2062(Closure , Object ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.