Alejandro H
Alejandro H

Reputation: 412

Issue with AutoMapper having Unmapped properties

Ok, so first of all, what I am trying to do is get user details from Registration form in angular and register those details in to the SQL Server database. I have been following a couple of tutorials and I am wondering why is it that when I run the command to make a new migration it creates a table with a lot of different properties, I did not specify.

For example, by default it creates these properties:

migrationBuilder.CreateTable(
                name: "User",
                columns: table => new
                {
                    Id = table.Column<string>(nullable: false),
                    UserName = table.Column<string>(maxLength: 256, nullable: true),
                    NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
                    Email = table.Column<string>(maxLength: 256, nullable: true),
                    NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
                    EmailConfirmed = table.Column<bool>(nullable: false),
                    PasswordHash = table.Column<string>(nullable: true),
                    SecurityStamp = table.Column<string>(nullable: true),
                    ConcurrencyStamp = table.Column<string>(nullable: true),
                    PhoneNumber = table.Column<string>(nullable: true),
                    PhoneNumberConfirmed = table.Column<bool>(nullable: false),
                    TwoFactorEnabled = table.Column<bool>(nullable: false),
                    LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
                    LockoutEnabled = table.Column<bool>(nullable: false),
                    AccessFailedCount = table.Column<int>(nullable: false)
                },

I do not know where these properties come from and I would like to know if I could change this. I have made one website following a tutorial, but now I am trying to experiment a new project on my own. So, the problem is that when using AutoMapper I get this error message, I would like to know how to solve this problem:

AutoMapper created this type map for you, but your types cannot be mapped using the current configuration. AccountModel -> ApplicationUser (Destination member list) UserWebAPI.Models.AccountModel -> UserWebAPI.Models.ApplicationUser (Destination member list)

Unmapped properties: Id NormalizedUserName NormalizedEmail EmailConfirmed PasswordHash SecurityStamp ConcurrencyStamp PhoneNumber PhoneNumberConfirmed TwoFactorEnabled LockoutEnd LockoutEnabled AccessFailedCount

AccountController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using UserWebAPI.Models;
using AutoMapper;
using Microsoft.Extensions.Configuration;

namespace UserWebAPI.Controllers
{
    public class AccountController : ControllerBase
    {
        private readonly IConfiguration _config;
        private readonly IMapper _mapper;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SignInManager<ApplicationUser> _signInManager;

        public AccountController (IConfiguration config, 
            IMapper mapper,
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _mapper = mapper;
            _config = config;
        }

        [Route("api/User/Register", Name = "GetUser") ]
        [HttpPost]
        public async Task<ActionResult> Register(AccountModel model) //add async Task<Result>
        {
            //var userStore = new UserStore<ApplicationUser>(new DataContext());
            var userStore = _mapper.Map<ApplicationUser>(model);
            //var manager = new UserManager<ApplicationUser>(userStore);
            var manager = await _userManager.CreateAsync(userStore, model.Password);
            var user = new ApplicationUser() { UserName = model.UserName, Email = model.Email };
            //var user = _mapper.Map<ApplicationUser>(userStore);
            user.FirstName = model.FirstName;
            user.LastName = model.LastName;

            if (manager.Succeeded)
            {
                //IdentityResult result = manager.Create(user, model.Password);
                return CreatedAtRoute("GetUser", new { id = userStore.Id }, user);
            }
            return BadRequest(manager.Errors);
        }

    }
}

AccountModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace UserWebAPI.Models
{
    public class AccountModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

IdentityModel.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace UserWebAPI.Models
{
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class DataContext : IdentityDbContext<ApplicationUser> //DataContext instead of ApplicationDbContext
    {
        public DataContext(DbContextOptions<DataContext> options)
            : base(options)
        {
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            //AspNetUsers -> User
            builder.Entity<ApplicationUser>()
                .ToTable("User");
            //AspNetRoles -> Role
            builder.Entity<IdentityRole>()
                .ToTable("Role");
            //AspNetRoles -> UserRole
            builder.Entity<IdentityUserRole<string>>()
                .ToTable("UserRole");
            //AspNetUserClaims -> UserClaim
            builder.Entity<IdentityUserClaim<string>>()
                .ToTable("UserClaim");
            //AspNetUserLogins -> UserLogin
            builder.Entity<IdentityUserLogin<string>>()
                .ToTable("UserLogin");
        }
    }
}

Upvotes: 0

Views: 508

Answers (1)

Ryan
Ryan

Reputation: 20116

I am wondering why is it that when I run the command to make a new migration it creates a table with a lot of different properties, I did not specify.

Since you ApplicationUser inherits the IdentityUser, when you do migration, it will create the table with those properties by default.You could press F12 to check the IdentityUser model in vs( see the IdentityUser<string> which it inherits).

Also refer to Identity model customization in ASP.NET Core

MappingProfile.cs:

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<AccountModel, ApplicationUser>();
    }
}

Upvotes: 1

Related Questions