AutoMapper 具有未映射属性的问题

Posted

技术标签:

【中文标题】AutoMapper 具有未映射属性的问题【英文标题】:Issue with AutoMapper having Unmapped properties 【发布时间】:2019-12-06 07:40:08 【问题描述】:

好的,首先,我要做的是从 Angular 注册表单中获取用户详细信息,并将这些详细信息注册到 SQL Server 数据库中。我一直在关注一些教程,我想知道为什么当我运行命令进行新迁移时,它会创建一个具有许多不同属性的表,我没有指定。

例如,默认情况下它会创建以下属性:

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)
                ,

我不知道这些属性是从哪里来的,我想知道是否可以更改它。我按照教程制作了一个网站,但现在我正在尝试自己尝试一个新项目。所以,问题是在使用 AutoMapper 时收到此错误消息,我想知道如何解决此问题:

AutoMapper 为您创建了此类型映射,但您的类型无法使用当前配置进行映射。 AccountModel -> ApplicationUser(目标成员列表) UserWebAPI.Models.AccountModel -> UserWebAPI.Models.ApplicationUser(目标成员列表)

未映射的属性: ID 标准化用户名 标准化电子邮件 电子邮件确认 密码哈希 安全邮票 并发戳 电话号码 电话号码已确认 启用双因素 锁定结束 LockoutEnabled 访问失败次数

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");
        
    

【问题讨论】:

【参考方案1】:

我想知道为什么当我运行命令进行新迁移时,它会创建一个具有许多不同属性的表,我没有指定。

由于你ApplicationUser继承了IdentityUser,当你进行迁移时,它会默认创建具有这些属性的表。你可以按F12在vs中检查IdentityUser模型(参见IdentityUser&lt;string&gt;它继承)。

另请参阅Identity model customization in ASP.NET Core

MappingProfile.cs:

public class MappingProfile : Profile

    public MappingProfile()
    
        CreateMap<AccountModel, ApplicationUser>();
    

【讨论】:

修复了这个问题,但是有一个新问题:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] 执行请求时发生未处理的异常。 System.ArgumentNullException:值不能为空。参数名称:密码。我不知道这是角度问题还是 c# 问题。我可能不得不问一个新问题。

以上是关于AutoMapper 具有未映射属性的问题的主要内容,如果未能解决你的问题,请参考以下文章

Automapper 无法在单元测试项目中映射外键属性

[使用Automapper时,我是否也应该展平/映射视图模型的内部objetc?

一文为你详细讲解对象映射库AutoMapper所支持场景

忽略使用 Automapper 映射一个属性

如何使用automapper映射与多个表的数据集

AutoMapper 根据其他模型属性值映射所有属性