Base solution for your next web application

Activities of "wizgod"

Greetings Programs!

I have used the following to remove the table prefixes for all versions up to 9 (.Net Core + Angular) with no issues.

modelBuilder.ChangeAbpTablePrefix<Tenant, Role, User>("");

In v10, with a clean install, I had to change the Target Framework to .NET 5.0 in order to run.

I successfully executed update-database to create the initial tables.

When I went to change the table prefix with the line above, I received the error below.

Is there any additional configuration I need to make for v10?

Thanks,

Wg

System.InvalidOperationException: Both 'TenantFeatureSetting' and 'EditionFeatureSetting' are mapped to the table 'AbpFeatures'. All the entity types in a hierarchy that don't have a discriminator must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.ValidateTPTMapping(IEntityType rootEntityType, Boolean forTables)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.ValidateInheritanceMapping(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IModel model)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, ModelDependencies modelDependencies)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, ModelDependencies modelDependencies)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.&lt;&gt;c__DisplayClass0_0.&lt;.ctor&gt;b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.&lt;&gt;c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Both 'TenantFeatureSetting' and 'EditionFeatureSetting' are mapped to the table 'AbpFeatures'. All the entity types in a hierarchy that don't have a discriminator must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.

Hi @maliming,

Yes, thanks,

Wg

Hi @maliming,

I was updating entites (that implemented IMustHaveTenant) prior to sending the notification and I found that I needed to call CurrentUnitOfWork.SaveChangesAsync() before sending the notification.

Thanks,

Wg

Hi @maliming,

Version 8.5.0.

Here is the full class; I create a new list of Abp.UserIdentifier(tenant, userId) and there are values for the parameters being passed to PublishAsync.

Thanks,

Wg

    public class UserNotificationAppService : WizgodIncAppServiceBase, IUserNotificationAppService
    {
        private readonly INotificationPublisher _notificationPublisher;
        private readonly IUserAppService _userAppService;
        private readonly ITimeSheetApproversAppService _timeSheetApproversAppService;
        public UserNotificationAppService(INotificationPublisher notificationPublisher,
            IUserAppService userAppService,
            ITimeSheetApproversAppService timeSheetApproversAppService)
        {
            _notificationPublisher = notificationPublisher;
            _userAppService = userAppService;
            _timeSheetApproversAppService = timeSheetApproversAppService;
        }

        [AbpAllowAnonymous]
        public virtual async Task SendNotificationToApprovers(long fromUserId, string url, string message, string notificationName, int severity)
        {
            var user = await _userAppService.GetUser(new EntityDto<long> {Id = fromUserId});

            if (!user.TimeSheetApproversId.HasValue) return;

            var timeSheetApprovers = 
                await _timeSheetApproversAppService.GetTimeSheetApprovers(
                    new EntityDto {Id = user.TimeSheetApproversId.Value});

            var approverIds = new List<long?> { timeSheetApprovers.ApproverId };

            if (timeSheetApprovers.FirstBackupApproverId.HasValue) approverIds.Add(timeSheetApprovers.FirstBackupApproverId.Value);
            if (timeSheetApprovers.SecondBackupApproverId.HasValue) approverIds.Add(timeSheetApprovers.SecondBackupApproverId.Value);

            var userIds = approverIds.Select(q => new Abp.UserIdentifier(2, q.Value)).ToArray();

            message = message.Replace("[Name]", user.Name)
                .Replace("[Surname]", user.Surname)
                .Replace("[EmployeeID]", user.EmployeeId);

            var data = new MessageNotificationData(message) {["url"] = url};

            await _notificationPublisher.PublishAsync(notificationName, data, null,(NotificationSeverity)severity, userIds);
        }

        [AbpAllowAnonymous]
        public virtual async Task SendNotificationToUser(long fromUserId, string url, string message, string notificationName, int notificationServerity, long userId)
        {
            await SendNotificationToUsers(fromUserId, url, message, notificationName, notificationServerity, new[] { userId });
        }

        [AbpAllowAnonymous]
        public virtual async Task SendNotificationToUsers(long fromUserId, string url, string message, string notificationName, int severity, long[] userIds)
        {
            var user = await UserManager.GetUserByIdAsync(fromUserId);

            var userIdentifiers = userIds.Select(q => new Abp.UserIdentifier(2, q)).ToArray();

            message = message.Replace("[Name]", user.Name)
                .Replace("[Surname]", user.Surname)
                .Replace("[EmployeeID]", user.EmployeeId);

            var data = new MessageNotificationData(message) {["url"] = url};

            await _notificationPublisher.PublishAsync(notificationName, data, severity: (NotificationSeverity)severity, userIds: userIdentifiers);
        }
    }

Greetings Programs!

When I execute this code: <br>

        var userIds = approverIds.Select(q => new Abp.UserIdentifier(2, q.Value)).ToArray();
        message = message.Replace("[Name]", user.Name)
            .Replace("[Surname]", user.Surname)
            .Replace("[EmployeeID]", user.EmployeeId);

        var data = new MessageNotificationData(message) {["url"] = url};

        await _notificationPublisher.PublishAsync(notificationName, data, null,(NotificationSeverity)severity, userIds);

<br> I am receiving the following error:

ERROR 2020-04-22 16:58:30,000 [8    ] Mvc.ExceptionHandling.AbpExceptionFilter - Can not set TenantId to 0 for IMustHaveTenant entities! Abp.AbpException: Can not set TenantId to 0 for IMustHaveTenant entities! at Abp.EntityFrameworkCore.AbpDbContext.CheckAndSetMustHaveTenantIdProperty(Object entityAsObj) at Abp.EntityFrameworkCore.AbpDbContext.ApplyAbpConceptsForAddedEntity(EntityEntry entry, Nullable`1 userId, EntityChangeReport changeReport) at Abp.EntityFrameworkCore.AbpDbContext.ApplyAbpConcepts(EntityEntry entry, Nullable`1 userId, EntityChangeReport changeReport) at Abp.EntityFrameworkCore.AbpDbContext.ApplyAbpConcepts() at Abp.EntityFrameworkCore.AbpDbContext.SaveChangesAsync(CancellationToken cancellationToken) at Abp.Zero.EntityFrameworkCore.AbpZeroCommonDbContext`3.SaveChangesAsync(CancellationToken cancellationToken) at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesInDbContextAsync(DbContext dbContext) at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesAsync() at Abp.Notifications.NotificationStore.InsertNotificationAsync(NotificationInfo notification) at Abp.Domain.Uow.UnitOfWorkInterceptor.InternalInterceptAsynchronous(IInvocation invocation) at Abp.Notifications.NotificationPublisher.PublishAsync(String notificationName, NotificationData data, EntityIdentifier entityIdentifier, NotificationSeverity severity, UserIdentifier[] userIds, UserIdentifier[] excludedUserIds, Nullable`1[] tenantIds)

Thanks,

Wg

@ismcagdas, I've figured it out; it was an oversight on my part.

When I was migrating the users, I was setting the new NormalizedUserName column with UPPER(Name + ' ' + Surname) instead of UPPER(UserName).

Thanks,

Wg

Hi @ismcagdas,

Has that method changed for 8.5.0?

It's saying that _passwordHasher is not accessable because it's private.

Thanks,

Wg

Hi @ismcagdas,

Will do. I'll let you know in about 10 days; tied up till then.

Thanks,

Wg

Hi @ismcagdas,

I added that code and overrode the method in LogInManager.

At:

var user = await UserManager.FindByNameOrEmailAsync(tenantId, userNameOrEmailAddress);

  • It can't find the user when userNameOrEmailAddress is the username; the value returns null (the correct tenantId is passed).
  • It does find the user if the email address is used.
  • If I switch back to loging in with the username after using the email address, it finds the user.

When it's null,it trys to create the object and the "Email is already taken" exception is thrown at:

await UserManager.CreateAsync(user);

Hi @ismcagdas,

Abp and Abp.* packages are v5.4.0 with Abp.AspNetZeroCore and Abp.AspNetZeroCore.Web being v2.0.0.

Showing 11 to 20 of 50 entries