Open Closed

Login Exception when using Custom Data Module #521


0
byteplatz created

Hello,

After moving to the next step of my separated solution with custom module, I have created the unitofwork/crud operation of a very basic entity. New DataModule created tests running ok.

I have updated the nuget package from main app, and when I log in I get this exception

System.NotSupportedException: The specified LINQ expression contains references to queries that are associated with different contexts.

The exception is being raised at :

var loginResult = await _userManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);

from AccountController:

private async Task<AbpUserManager<Tenant, Role, User>.AbpLoginResult> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
        {
            var loginResult = await _userManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    return loginResult;
                default:
                    throw CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
            }
        }

I have folowed Sample.Blog and changed to v1.6 accordingly

Any ideas ?

It looks like the DI is injecting the Custom Module DbContext into AccountController (UserManager) and trying to mix them up...

Bruno


9 Answer(s)
  • 0
    byteplatz created

    I think its related to upgrade to 0.7.4.1 (the sample blog module is using 0.6.4.1).

    The constructors for AbpUserManager has changed and now include IUnitOfWorkManager

    Maybe something related to it.

    May I ask you to update the blog sample using latest versions so I can make sure its working OOB before customizing it ?

    Please, Im stuck on this

    Bruno

  • 0
    byteplatz created

    If I use a shared library from main app (to share Tenant/Role/User) I got 2 things:

    1. In My custom module DbContext I have to ignore few entities:
    modelBuilder.Ignore<AuditLog>();
                modelBuilder.Ignore<EditionFeatureSetting>();
                modelBuilder.Ignore<Edition>();
                modelBuilder.Ignore<FeatureSetting>();
                modelBuilder.Ignore<ApplicationLanguage>();
                modelBuilder.Ignore<ApplicationLanguageText>();
                modelBuilder.Ignore<PermissionSetting>();
                modelBuilder.Ignore<RolePermissionSetting>();
                modelBuilder.Ignore<Role>();
                modelBuilder.Ignore<Setting>();
                modelBuilder.Ignore<TenantFeatureSetting>();
                modelBuilder.Ignore<Tenant>();
                modelBuilder.Ignore<UserLogin>();
                modelBuilder.Ignore<UserPermissionSetting>();
                modelBuilder.Ignore<UserRole>();
                modelBuilder.Ignore<User>();
    
    1. When I run main app I get
    ERROR 2015-11-21 11:04:00,749 [5    ] Abp.Web.Mvc.Controllers.AbpHandleErrorAttribute - System.InvalidOperationException: The entity type AuditLog is not part of the model for the current context.
       em System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType)
       em System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       em System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       em System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
       em System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
       em System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
       em System.Data.Entity.DbSet`1.Add(TEntity entity)
       em Abp.EntityFramework.Repositories.EfRepositoryBase`3.InsertAsync(TEntity entity)
       em Castle.Proxies.EfRepositoryBase`3Proxy_8.InsertAsync_callback(AuditLog entity)
       em Castle.Proxies.Invocations.EfRepositoryBase`3_InsertAsync_12.InvokeMethodOnTarget()
       em Castle.DynamicProxy.AbstractInvocation.Proceed()
       em Abp.Domain.Uow.UnitOfWorkInterceptor.PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options)
       em Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation, UnitOfWorkOptions options)
       em Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation)
       em Castle.DynamicProxy.AbstractInvocation.Proceed()
       em Castle.Proxies.EfRepositoryBase`3Proxy_8.InsertAsync(AuditLog entity)
       em Abp.Auditing.AuditingStore.SaveAsync(AuditInfo auditInfo)
       em Abp.Auditing.AuditingStoreExtensions.&lt;&gt;c__DisplayClass1.&lt;Save&gt;b__0()
       em System.Threading.Tasks.Task`1.InnerInvoke()
       em System.Threading.Tasks.Task.Execute()
    --- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
       em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       em Nito.AsyncEx.AsyncContext.<>c__DisplayClass3.<Run>b__1(Task t)
       em System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
       em System.Threading.Tasks.Task.Execute()
    --- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
       em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       em Nito.AsyncEx.AsyncContext.Run(Func`1 action)
       em Abp.Auditing.AuditingStoreExtensions.Save(IAuditingStore auditingStore, AuditInfo auditInfo)
       em Abp.Web.Mvc.Controllers.AbpController.HandleAuditingAfterAction(ActionExecutedContext filterContext)
       em Abp.Web.Mvc.Controllers.AbpController.OnActionExecuted(ActionExecutedContext filterContext)
       em System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass33.&lt;BeginInvokeActionMethodWithFilters&gt;b__32(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass21.&lt;&gt;c__DisplayClass2b.&lt;BeginInvokeAction&gt;b__1c()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__1e(IAsyncResult asyncResult)
    System.InvalidOperationException: The entity type AuditLog is not part of the model for the current context.
       em System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType)
       em System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
       em System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
       em System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
       em System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
       em System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity)
       em System.Data.Entity.DbSet`1.Add(TEntity entity)
       em Abp.EntityFramework.Repositories.EfRepositoryBase`3.InsertAsync(TEntity entity)
       em Castle.Proxies.EfRepositoryBase`3Proxy_8.InsertAsync_callback(AuditLog entity)
       em Castle.Proxies.Invocations.EfRepositoryBase`3_InsertAsync_12.InvokeMethodOnTarget()
       em Castle.DynamicProxy.AbstractInvocation.Proceed()
       em Abp.Domain.Uow.UnitOfWorkInterceptor.PerformAsyncUow(IInvocation invocation, UnitOfWorkOptions options)
       em Abp.Domain.Uow.UnitOfWorkInterceptor.PerformUow(IInvocation invocation, UnitOfWorkOptions options)
       em Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept(IInvocation invocation)
       em Castle.DynamicProxy.AbstractInvocation.Proceed()
       em Castle.Proxies.EfRepositoryBase`3Proxy_8.InsertAsync(AuditLog entity)
       em Abp.Auditing.AuditingStore.SaveAsync(AuditInfo auditInfo)
       em Abp.Auditing.AuditingStoreExtensions.<>c__DisplayClass1.<Save>b__0()
       em System.Threading.Tasks.Task`1.InnerInvoke()
       em System.Threading.Tasks.Task.Execute()
    --- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
       em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       em Nito.AsyncEx.AsyncContext.&lt;&gt;c__DisplayClass3.&lt;Run&gt;b__1(Task t)
       em System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
       em System.Threading.Tasks.Task.Execute()
    --- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---
       em System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       em System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       em Nito.AsyncEx.AsyncContext.Run(Func`1 action)
       em Abp.Auditing.AuditingStoreExtensions.Save(IAuditingStore auditingStore, AuditInfo auditInfo)
       em Abp.Web.Mvc.Controllers.AbpController.HandleAuditingAfterAction(ActionExecutedContext filterContext)
       em Abp.Web.Mvc.Controllers.AbpController.OnActionExecuted(ActionExecutedContext filterContext)
       em System.Web.Mvc.Controller.System.Web.Mvc.IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
       em System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
    
  • 0
    byteplatz created

    I manage to find the root cause but could not find a solution yet

    The problem is the Dbcontext from the custom (separated) module...

    When we inherit from AbpZeroDbContext we must provide the same contexto key in order to mange migrations.

    We also need to provide Tenant/Role/User.

    Im not sure if this is the right approach when using modulezero...

    I will try using a DbContext without inherit it from AbpZeroDbContext but Im afraid I will loose multitenancy functionality...

    Halil, can you please help up ?

    Bruno

  • 0
    hikalkan created
    Support Team

    Working on it. I will inform you very soon. Thanks.

  • 0
    byteplatz created

    Thank you

    If I inherit from AbpDbContext everyhing Works fine...just wonder id this is expected.

    Bruno

  • 0
    hikalkan created
    Support Team

    Hi,

    I hope that your problem will be resolved with the latest module-zero upgrade and sample blog code changes.

    Look at the AutoRepositoryTypes attribute on <a class="postlink" href="https://github.com/aspnetboilerplate/sample-blog-module/blob/master/src/Abp.Samples.Blog.EntityFramework/AbpZeroSampleDbContext.cs#L14">https://github.com/aspnetboilerplate/sa ... ext.cs#L14</a>

    Why? The problem:

    ABP has a feature to create auto repository. You can inject IRepository<UserLogin> for example without defining it. ABP searchs all dbcontext classes and finds dbset properties and create an auto repository for each. What if UserLogin defined in more than one dbcontext? When we inherit a dbcontext, it happens. Solution is that: We must use different type of repository interface for our module, so ABP can know which dbcontext is used. It uses MainDbContext for IRepository<UserLogin> and BlogDbContext for IBlogRepository<UserLogin>.

    This makes writing modules a bit harder. But no other choice (modularity is a hard stuff itself :))

    Have a nice day.

  • 0
    byteplatz created

    Thank you...it seems promising.

    The only thing I still want to understand is : Why do we need to inherit from AbpZerodbContext ? Is it to be able to use (injected) tenantmanager/usermanager so the custom module can query without being coupled to main app ?

    Bruno

  • 0
    hikalkan created
    Support Team

    Hi,

    Actually, we don't have to.. But if we want to query users, for example, we have two options:

    1. Inherit from abpzerodbcontext, user entity, usermanager and so on... and use usermanager...
    2. We don't inherit from abpzerodbcontext or user entity, we create our own user entity, say BlogUser, map to Users table (even we don't map every property, just what we need). Then we can use IRepository<BlogUser> and so on...
  • 0
    byteplatz created

    Thank you

    That was what I wanted to hear :)

    My feeling was right..

    So I will only inherit if needed :)

    Cheers

    Bruno