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

ASP.NET Core中NormalizedEmail未写入AspNetUsers表问题求助

Asp.Net Identity中NormalizedEmail未写入AspNetUsers表的排查与解决

问题描述

我在多个项目中使用Asp.Net Identity管理器均运行正常,对比其他代码库,除了Startup类中的密码规则覆盖外,逻辑完全一致,但无法理解为何NormalizedEmail字段未被添加到AspNetUsers表中。

相关代码

Startup.cs 配置代码

.AddEntityFrameworkStores<CorporateIdentityContext>()
.AddDefaultTokenProviders();

//override identity Password rule
services.Configure<IdentityOptions>(opts => {
    opts.Password.RequiredLength = 6;
    opts.Password.RequireNonAlphanumeric = false;
    opts.Password.RequireLowercase = false;
    //opts.Password.RequireUppercase = true;
    opts.Password.RequireDigit = false;
    opts.User.RequireUniqueEmail = true;
    //opts.SignIn.RequireConfirmedEmail = false;
    opts.User.AllowedUserNameCharacters =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    //options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+/";
    //opts.User.AllowedUserNameCharacters = null;
});

用户创建方法代码

public async Task<ServiceResponse<GetUserDto>> RegisterUser(UserDto payload)
{
    var serviceResponse = new ServiceResponse<GetUserDto>();

    //检查用户是否存在
    var CorporateUser = await _userManager.FindByNameAsync(payload.Email);

    if (CorporateUser != null)
    {
        _logger.LogInformation($"User already exist for this email: {CorporateUser.Email}");
        serviceResponse.Message = $"User already exist for this email: {CorporateUser.Email}";
        serviceResponse.Success = false;
        return serviceResponse;
    }
     
    var password = Helper.ServiceHelper.GeneratePassword(7);
    var uniqueId = ServiceHelper.GeneratePolNumber();
    var refnum = ServiceHelper.GeneratePropNumber();

    var newUser = new CorporateIdentityUser
    {
        Email = payload.Email,
        UserName = payload.UserName,
        UserUniqueId = uniqueId,
        NormalizedEmail = payload.Email.ToUpper(),
        //NormalizedUserName = payload.Email,
        RefrenceId = refnum,
        FirstName = payload.FirstName,
        LastName = payload.LastName,
        CompanyName = payload.CompanyName,
        BrokerName = payload.BrokerName,
        AccountType = "Generaluser",
        Country = payload.Country,
        RcNumber = payload.RcNumber,
        DateCreated = DateTime.Now,
        Address = payload.Address,
        Occupation = payload.Occupation,
        Gender =payload.Gender,
        DateofBirth = payload.DateofBirth,
        IsActive = false,
        IsWallet = false,
        IsBroker = false,
        PhoneNumber = payload.PhoneNumber,
        SecurityStamp = Guid.NewGuid().ToString()
    };

    try
    {
        var result = await _userManager.CreateAsync(newUser, password);

        if (!result.Succeeded)
        {
            var errorMsg = string.Empty;
            foreach (var error in result.Errors)
            {
                _logger.LogError($"The error occur while registring {newUser.Email}: {error.Code}, {error.Description}");
                errorMsg = error.Description;
            }
            serviceResponse.Message = errorMsg;
            serviceResponse.Success = false;
        }
        else
        {
            var confirmEmailToken = await _userManager.GenerateEmailConfirmationTokenAsync(newUser);
            var encodedEmailToken = Encoding.UTF8.GetBytes(confirmEmailToken);
            var validEmailtoken = WebEncoders.Base64UrlEncode(encodedEmailToken);

            var body = new Dictionary<string, object>()
            {
                { "name",   payload.FirstName.ToUpper() +" "+ payload.LastName},
                { "password", password},
                {"email", payload.Email },
                {"temp_id", 27059391}
            };

            await Helper.ServiceHelper.SendEmailVerificationViaPostmarkAsync(body);
           
            serviceResponse.Data = _mapper.Map<GetUserDto>(newUser);
            serviceResponse.Message = "Registration Successful";
            serviceResponse.Success = true;

            _logger.LogInformation($"Registration successfull for this username: {newUser.Email}");
        }
    }
    catch (Exception ex)
    {
        string error = ex.Message;
        serviceResponse.Message= error;
        _logger.LogError($"Error occured! Message {ex.Message} Stack Trace {ex.StackTrace}");
    }
    return serviceResponse;
}

排查方向与解决方案

1. 移除手动赋值,依赖UserManager自动处理

Asp.Net Identity的UserManager.CreateAsync方法内部会自动规范化NormalizedEmail和NormalizedUserName,遵循IdentityOptions中的配置。手动赋值的NormalizedEmail可能被该方法的内部逻辑覆盖,导致最终写入数据库的值异常(或为空)。

解决方案:删除newUser初始化时的NormalizedEmail = payload.Email.ToUpper()代码,让UserManager自动完成规范化操作。

2. 检查实体类定义

确保CorporateIdentityUser正确继承自IdentityUser,这样才能继承NormalizedEmail等核心属性,且EF Core能正确映射到数据库表:

public class CorporateIdentityUser : IdentityUser
{
    // 自定义属性
    public string UserUniqueId { get; set; }
    public string RefrenceId { get; set; }
    // ...其他自定义属性
}

如果是完全自定义的属性,需确保NormalizedEmail为public属性,且通过数据注解(如[Column("NormalizedEmail")])或Fluent API正确映射到数据库字段。

3. 验证数据库表结构

确认AspNetUsers表中存在NormalizedEmail列,若不存在,需生成EF Core迁移并更新数据库:

# 生成迁移
Add-Migration AddNormalizedEmailColumn
# 更新数据库
Update-Database

4. 调试验证

在调用CreateAsync前后分别打印newUser.NormalizedEmail的值,观察是否被修改;同时启用EF Core日志,查看插入语句中是否包含NormalizedEmail字段,确认数据库操作的细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:35:26