You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoMapper映射异常:User实体FirstName字段未成功映射排查

问题:AutoMapper映射UserForRegistrationDto到User实体时,FirstName字段未写入数据库

相关代码

User实体

namespace Pharma.Models
{
    public partial class User
    {
        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string Email { get; set; }
        public bool Active { get; set; }

        public User()
        {
            if (FirstName == null)
            {
                FirstName = "";
            }

            if (Email == null)
            {
                Email = "";
            }

        }

    }
}

UserForRegistrationDto

namespace Pharma.DTOs
{
    public partial class UserForRegistrationDto
    {
        public string Email { get; set; }
        public string Password { get; set; }
        public string PasswordConfirm { get; set; }
        public string FirstName { get; set; }

        public UserForRegistrationDto()
        {
            if (Email == null)
            {
                Email = "";
            }
            if (Password == null)
            {
                Password = "";
            }
            if (PasswordConfirm == null)
            {
                PasswordConfirm = "";
            }
            if (FirstName == null)
            {
                FirstName = "";
            }

        }
    }
}

AuthController映射与注册逻辑

public class AuthController
{
    private readonly AuthHelper _authHelper;
    IAuthRepository _authRepository;
    IUserRepository _userRepository;

    IMapper _mapper;

    public AuthController(IConfiguration config, IAuthRepository authRepository, IUserRepository userRepository)
    {
        _authHelper = new AuthHelper(config);
        _authRepository = authRepository;
        _userRepository = userRepository;
        _mapper = new Mapper(new MapperConfiguration(cfg =>
       {
           cfg.CreateMap<UserForRegistrationDto, User>();
       }));

    }

    [HttpPost("Register")]
    public async void RegisterAsync(UserForRegistrationDto userForRegistration)
    {
        byte[] passwordSalt = new byte[128 / 8];
        // 检查密码与确认密码是否一致
        if (userForRegistration.Password != userForRegistration.PasswordConfirm)
        {
            throw new Exception("Incorrect credentials!");
        }
        // 检查邮箱是否已存在
        if (await _authHelper.DoesUserExistByEmailAsync(userForRegistration.Email!))
        {
            throw new Exception("User already exists!");
        }
        
        _authHelper.GetPasswordHash(userForRegistration.Password, passwordSalt);
        byte[] passwordHash = [];
        byte[] passwordHashed = _authHelper.GetPasswordHash(userForRegistration.Password, passwordSalt);
        string EmailForRegister = userForRegistration.Email;
     
        List<SqlParameter> sqlParameters = new List<SqlParameter>();
       
        SqlParameter passwordSaltParameter = new SqlParameter("@PasswordSalt", SqlDbType.VarBinary);
        passwordSaltParameter.Value = passwordSalt;
        SqlParameter passwordHashParameter = new SqlParameter("@PasswordHash", SqlDbType.VarBinary);
        passwordHashParameter.Value = passwordHash;
        sqlParameters.Add(passwordSaltParameter);
        sqlParameters.Add(passwordHashParameter);
        Console.WriteLine(sqlParameters);
       
        UserToRegisterAuthDto userToRegisterAuthDto = new UserToRegisterAuthDto
        {
            Email = EmailForRegister,
            passwordHash = passwordHashed,
            passwordSalt = passwordSalt
        };
      
        _authRepository.AddEntity<UserToRegisterAuthDto>(userToRegisterAuthDto);
    
        User userDb = _mapper.Map<User>(userForRegistration);
        _userRepository.AddEntity<User>(userDb);
        _userRepository.SaveChanges();
        _authRepository.SaveChanges();
    }
}

DataContext配置

using Microsoft.EntityFrameworkCore;
using Pharma.Models;

namespace Pharma.Data
{
    public class DataContextEF : DbContext
    {
        private readonly IConfiguration _config;

        public DataContextEF(IConfiguration config)
        {
            _config = config;
        }

        public virtual DbSet<User> Users { get; set; }
        public virtual DbSet<Substance> Substances { get; set; }
        public virtual DbSet<Dosage> Dosages { get; set; }
        public virtual DbSet<Product> Products { get; set; }

        public virtual DbSet<UserToRegisterAuthDto> UsersAuth { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder
                    .UseSqlServer(_config.GetConnectionString("DefaultConnection"),
                        optionsBuilder => optionsBuilder.EnableRetryOnFailure());
            }
        }


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasDefaultSchema("dbo");

            modelBuilder.Entity<User>()
                .ToTable("Users", "dbo")
                .HasKey(u => u.UserId);

            modelBuilder.Entity<Substance>()
                .ToTable("Substances", "dbo")
                .HasKey(u => u.SubstanceId);

            modelBuilder.Entity<Dosage>()
                .ToTable("Dosages", "dbo")
                .HasKey(u => u.DosageId);

            modelBuilder.Entity<Product>()
                .ToTable("Products", "dbo")
                .HasKey(u => u.ProductId);

            modelBuilder.Entity<UserToRegisterAuthDto>()
                .ToTable("Auth2", "dbo")
                .HasKey(u => u.Email);

        }

    }
}

问题排查与解决方案

1. 先确认请求数据是否包含FirstName

在RegisterAsync方法开头加调试代码,检查前端传入的Dto里FirstName是否有值:

// 调试输出,确认接收的FirstName内容
Console.WriteLine($"Received FirstName: {userForRegistration.FirstName}");

如果输出为空,说明前端没传这个字段,先修复请求数据;如果有值,再往下排查。

2. 修正AutoMapper初始化方式

你现在手动在控制器里创建Mapper实例的方式不规范,容易导致映射规则加载异常。正确做法是用依赖注入:

  • 在Program.cs/Startup.cs注册AutoMapper:
    // 扫描所有包含映射配置的程序集
    builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
    
  • 修改控制器构造函数,注入IMapper:
    public AuthController(IConfiguration config, IAuthRepository authRepository, IUserRepository userRepository, IMapper mapper)
    {
        _authHelper = new AuthHelper(config);
        _authRepository = authRepository;
        _userRepository = userRepository;
        _mapper = mapper; // 使用注入的实例,不再手动创建
    }
    
  • (可选)创建独立的映射配置类:
    新建一个配置类让AutoMapper明确加载映射规则:
    namespace Pharma.Mappings
    {
        public class UserMappingProfile : Profile
        {
            public UserMappingProfile()
            {
                // 显式声明映射,避免自动映射失效
                CreateMap<UserForRegistrationDto, User>()
                    .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
                    .ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email));
            }
        }
    }
    

3. 检查User实体的Active字段默认值

User实体的Active字段没有默认值,映射后的User对象中Active是默认的false,如果数据库该字段要求非空且无默认值,可能影响其他字段写入。可以在构造函数里给Active加默认值:

public User()
{
    FirstName = FirstName ?? "";
    Email = Email ?? "";
    Active = false; // 显式设置默认值
}

总结

最可能的原因是AutoMapper初始化方式错误导致自动映射规则未生效,其次是前端请求未传递FirstName字段。按照上述步骤逐一排查,即可解决问题。

内容的提问来源于stack exchange,提问作者user23278485

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:52:02