Open Closed

Issue adding user as navigation property from abp suite #338


User avatar
0
KittyJuggins created

When adding the user as a navigation property via the abp suite, there is always a build error pre add-migration. * Severity Code Description Project File Line Suppression State Suppression State Error CS0246 The type or namespace name 'AppUserDto' could not be found (are you missing a using directive or an assembly reference?) VideoMarking.Application.Contracts \aspnet-core\src\VideoMarking.Application.Contracts\Notes\NoteWithNavigationPropertiesDto.cs 12 Active

If we manually add the AppUserDto, the build error goes but when we manually run add-migration it errors with: The property 'AppUser.ExtraProperties' could not be mapped, because it is of type 'Dictionary<string, object>' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

The AppUserDto looks like this:

    public class AppUserDto : FullAuditedEntityDto<Guid>
    {
        public Guid? TenantId { get; private set; }

        public string UserName { get; private set; }

        public string Name { get; private set; }

        public string Surname { get; private set; }

        public string Email { get; private set; }

        public bool EmailConfirmed { get; private set; }

        public string PhoneNumber { get; private set; }

        public bool PhoneNumberConfirmed { get; private set; }


        public bool SEN { get; set; }
        public bool PupilPremium { get; set; }
        public bool EAL { get; set; }
        public bool ChildInCare { get; set; }
        public DateTime DateOfBirth { get; set; }
       }

We have tried adding b.ConfigureExtraProperties(); to the model builder in the dbcontext to no effect as suggested here: https://github.com/abpframework/abp/issues/1517 We have not been able to find a solution to this issue and we require the ability to link numerous entities to the user table.

Please can someone advise the proper way to achieve this.

Thanks

  • ABP Framework version: v3
  • UI type: Angular
  • Tiered (MVC) or Identity Server Seperated (Angular): no

17 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    you need to ignore ExtraProperties like this;

    CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties);
    

    check out the following question, similar one https://support.abp.io/QA/Questions/150/How-To-Create-a-Help-Desk-Ticket-Entity#answer-21da8121-ab88-ab2c-67f0-39f51d1b1819

  • User Avatar
    0
    KittyJuggins created

    Hi @Alper,

    Thanks for the response. I've added that line now, and followed step by step using the example given with the suite, but I am still getting the error

    `The property 'AppUser.ExtraProperties' could not be mapped, because it is of type 'Dictionary&lt;string, object&gt;' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'` on add-migration.
    
    

    The relevant section of my AutoMapperProfile file looks like:

                CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties);
    
                CreateMap<NoteCreateDto, Note>().IgnoreFullAuditedObjectProperties().Ignore(x => x.Id).Ignore(x => x.TenantId);
                CreateMap<NoteUpdateDto, Note>().IgnoreFullAuditedObjectProperties().Ignore(x => x.Id).Ignore(x => x.TenantId);
                CreateMap<Note, NoteDto>();
                CreateMap<NoteWithNavigationProperties, NoteWithNavigationPropertiesDto>();
                CreateMap<AppUser, LookupDto<Guid?>>().ForMember(dest => dest.DisplayName, opt => opt.MapFrom(src => src.Name));
    

    Please can you advise, Kitty

  • User Avatar
    0
    alper created
    Support Team Director

    you need to add the below line in BookStoreApplicationAutoMapperProfile.cs

    CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties);
    
  • User Avatar
    0
    KittyJuggins created

    As you can see in my previous reply, I have added it in the AutoMapperProfile file already and it still isn't working.

  • User Avatar
    0
    alper created
    Support Team Director

    kitty, there are multiple AutoMapperProfile classes. I just want to ensure that you have added it in the correct project.

  • User Avatar
    0
    KittyJuggins created

    Yes, its in the ApplicationAutoMapperProfile

  • User Avatar
    0
    yekalkan created
    Support Team Fullstack Developer

    Can you share the AppUser entity? And also the code piece which you add it to ModelBuilder in *DbContextModelCreatingExtensions.cs?

    Normally, using ConfigureByConvention should fix this.

    Example:

    
    builder.Entity&lt;IdentityUser&gt;(b =>
                {
                    b.ToTable(options.TablePrefix + "AppUsers", options.Schema);
    
                    .
                    .
                    .
                    b.ConfigureByConvention();
                    .
                    .
                    .
                }
    
  • User Avatar
    0
    KittyJuggins created

    Hi,

    The AppUser entity looks like:

    public class AppUser : FullAuditedAggregateRoot<Guid>, IUser
        {
            #region Base properties
    
            /* These properties are shared with the IdentityUser entity of the Identity module.
             * Do not change these properties through this class. Instead, use Identity module
             * services (like IdentityUserManager) to change them.
             * So, this properties are designed as read only!
             */
    
            public virtual Guid? TenantId { get; private set; }
    
            public virtual string UserName { get; private set; }
    
            public virtual string Name { get; private set; }
    
            public virtual string Surname { get; private set; }
    
            public virtual string Email { get; private set; }
    
            public virtual bool EmailConfirmed { get; private set; }
    
            public virtual string PhoneNumber { get; private set; }
    
            public virtual bool PhoneNumberConfirmed { get; private set; }
    
            #endregion
    
            public virtual bool SEN { get; set; }
            public virtual bool PupilPremium { get; set; }
            public virtual bool EAL { get; set; }
            public virtual bool ChildInCare { get; set; }
            public virtual DateTime DateOfBirth { get; set; }
            
            [ForeignKey("School")]
            public Guid? SchoolId { get; set; }
    
            public virtual School School { get; set; }
    
            [ForeignKey("Address")]
    
            public Guid? AddressId { get; set; }
    
            public virtual Address Address { get; set; }
    
            [ForeignKey("SchoolYear")]
            public Guid? SchoolYearId { get; set; }
    
            public virtual SchoolYear SchoolYear { get; set; }
    
            /* Add your own properties here. Example:
             *
             * public virtual string MyProperty { get; set; }
             * public string MyProperty { get; set; }
             *
             * If you add a property and using the EF Core, remember these;
             *
             * 1. update VideoMarkingDbContext.OnModelCreating
             * to configure the mapping for your new property
             * 2. Update VideoMarkingEfCoreEntityExtensionMappings to extend the IdentityUser entity
             * and add your new property to the migration.
             * 3. Use the Add-Migration to add a new database migration.
             * 4. Run the .DbMigrator project (or use the Update-Database command) to apply
             * schema change to the database.
             */
    
            private AppUser()
            {
                
            }
    

    The OnModelCreating() method looks like:

    protected override void OnModelCreating(ModelBuilder builder)
            {
                base.OnModelCreating(builder);
    
                /* Configure the shared tables (with included modules) here */
    
    
                builder.Entity<AppUser>(b =>
                {
                   
                    b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser
    
                    b.Property(p => p.DateOfBirth);
                    b.Property(p => p.SEN);
                    b.Property(p => p.ChildInCare);
                    b.Property(p => p.PupilPremium);
                    b.Property(p => p.EAL);
    
                    b.ConfigureByConvention();
    
                    b.ConfigureAbpUser();
    
                    
                    /* Configure mappings for your additional properties.
                     * Also see the VideoMarkingEfCoreEntityExtensionMappings class.
                     */
                });
    
                /* Configure your own tables/entities inside the ConfigureVideoMarking method */
    
                builder.ConfigureVideoMarking();
            }
    

    The Notes section in DbContextModelCreatingExtensions:

                builder.Entity<Note>(b =>
                {
                    b.ToTable(VideoMarkingConsts.DbTablePrefix + "Notes", VideoMarkingConsts.DbSchema);
                    b.ConfigureByConvention();
                    b.Property(x => x.TenantId).HasColumnName(nameof(Note.TenantId));
                    b.Property(x => x.Message).HasColumnName(nameof(Note.Message)).IsRequired();
                });
    
  • User Avatar
    0
    alper created
    Support Team Director

    Don't use navigation properties to other aggregate roots. See https://github.com/abpframework/abp/issues/1517

  • User Avatar
    0
    KittyJuggins created

    Note is not an aggregate root, it's a FullAuditedEntity. We need to be able to link user to it. Please can you advise on how we need to actually implement this.

    using VideoMarking.Users;
    using System;
    using Volo.Abp.Domain.Entities;
    using Volo.Abp.Domain.Entities.Auditing;
    using Volo.Abp.MultiTenancy;
    using JetBrains.Annotations;
    using Volo.Abp;
    
    namespace VideoMarking.Notes
    {
        public class Note : FullAuditedEntity<Guid>, IMultiTenant
        {
            public virtual Guid? TenantId { get; set; }
    
            [NotNull]
            public virtual string Message { get; set; }
            public Guid? AppUserId { get; set; }
    
            public AppUser AppUser { get; set; }
    
            public Note()
            {
    
            }
    
            public Note(Guid id, string message)
            {
                Id = id;
                Check.NotNull(message, nameof(message));
                Message = message;
            }
        }
    }
    
  • User Avatar
    0
    alper created
    Support Team Director

    @KittyJuggins , remove AppUser from Note and keep the AppUserId only. When you fetch Note from database, fetch the user in a seperate query . Then map the both to your DTO. This is the best practise

  • User Avatar
    1
    myke@mycra.co created

    Hey all, I have been following this thread and several similar to it for a while to try and solve the issue I am having of adding a Navigation Property to a User. I must be missing something really simple because no matter what I try I cannot get it to work. I decided to start from scratch with a blank project and take a screen recording of it to upload in hopes you can point out where I am going wrong. And hopefully this helps out everyone else with the issue.

    Here is the video. https://www.youtube.com/watch?v=i1VH8B06njs

    Started from scratch with ABP Suite

    • Created an Entity called "Note"
    • Added a property called Title
    • Generated
    • Rebuilt web project to ensure it worked
    • Added a DTO class
    • Added CreateMap and ignored the ExtraProperties
    • Added navigation property via ABP Suite for a User based on the screnshots provided HERE
    • Generated updates
    • Tweaked a couple of Menu related issues due to regeneration
    • Ran generation again and this is where the Extra Properties mapping issues comes in

    Not seen in the video is the suggestion of removing public AppUser AppUser { get; set; } from the Notes class. I do this, but it gets added back on while generating, which makes sense. I have only ever tried creating an Entity as a FullAuditedAggregateRoot because I want all the properties and features that come along with that. But I can see the OP states that this issue still persists even with a FullAuditedEntity.

  • User Avatar
    0
    alper created
    Support Team Director

    hi myke@mycra.co I just made a sample project for this topic. See https://community.abp.io/articles/how-to-add-the-user-entity-as-a-navigation-property-furp75ex


    Note this example is implemented with ABP Commercial 3.1.0-rc.3. This is a RC version. If you want to install the CLI and Suite RC version follow the next steps:

    1- Uninstall the current version of the CLI and install the specific RC version:

    dotnet tool uninstall --global Volo.Abp.Cli && dotnet tool install --global Volo.Abp.Cli --version 3.1.0-rc.3
    

    2- Uninstall the current version of the Suite and install the specific RC version:

    dotnet tool uninstall --global Volo.Abp.Suite && dotnet tool install -g Volo.Abp.Suite --version 3.1.0-rc.3 --add-source https://nuget.abp.io/<YOUR-API-KEY>/v3/index.json
    

    Don't forget to replace the <YOUR-API-KEY> with your own key!

  • User Avatar
    0
    myke@mycra.co created

    I appreciate you putting up an article about this! Is the source code located somewhere for that?

    I went through the steps outlined again(which mirrored the steps I have tried previously) and I end up with the same error as always 😞 Could it be my ABP Commercial version? I am running 3.0.5 on .NET Core 3.1 on macOS.

  • User Avatar
    0
    alper created
    Support Team Director

    I guess it's related a fix that's done in v3.1.0 (because we fixed some Suite issues in 3.1.0) Today we have released a new RC version (preview) of 3.1.0 - RC4 (the production of 3.1.0 will be released this weekend) Try to create a new project with 3.1.0-RC4 and we'll see if it's related with MAC or the framework.

  • User Avatar
    0
    myke@mycra.co created

    Success!!! Updated to the 3.1.0 release from today and this now works as expected. Screen Shot 2020-09-04 at 6.21.53 PM.png

  • User Avatar
    0
    alper created
    Support Team Director

    super! closing this

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on July 17, 2025, 06:22