【问题标题】:Asp.Net Identity save user without emailAsp.Net Identity 无需电子邮件即可保存用户
【发布时间】:2015-01-12 15:19:58
【问题描述】:

我想保存没有电子邮件的用户,如下所示:

var user = new ApplicationUser { UserName = model.Name };
var result = await UserManager.CreateAsync(user);

但我收到错误“电子邮件不能为空或为空”。有什么解决办法吗?还是不可能?

【问题讨论】:

  • 我有同样的问题,虽然Email 提供result 总是返回null 但成功。有解决办法吗?

标签: c# asp.net-identity-2


【解决方案1】:

我知道这是旧的,但我不同意接受的答案,因为该问题被标记为 asp.net-identity-2。为了未来读者的利益,ASP.NET Identity 2.0 对这个问题有一个非常简单的解决方案:

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    ...snip...
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            // This disables the validation check on email addresses
            RequireUniqueEmail = false
        };
        ...snip...
    }
}

UserValidator&lt;TUser&gt; 中,Task&lt;IdentityResult&gt; ValidateAsync(T item) 实现检查此标志并确定它是否应该运行电子邮件验证:

if (this.RequireUniqueEmail)
{
    await this.ValidateEmail(item, list);
}

既然你想保存没有电子邮件地址的用户,你应该这样做。

注意:仅应在未收集电子邮件地址时使用。如果您想收集和验证电子邮件地址,但在注册期间将其设为可选,则应使用自定义 IIdentityValidator

【讨论】:

  • 为您的头像加一个。 ...当然还有问题的正确答案! :)
【解决方案2】:

可以在App_Start\IdentityConfig.cs中设置ASP Identity 2.2

    manager.UserValidator = new UserValidator<ApplicationUser>(manager)
    {
        AllowOnlyAlphanumericUserNames = false,
        RequireUniqueEmail = false
    };

【讨论】:

    【解决方案3】:

    身份取决于电子邮件作为重置用户密码的一种方式。

    但是,忽略电子邮件并不简单,而是可能的。您需要实现忽略缺少电子邮件的Microsoft.AspNet.Identity.IIdentityValidator 接口:

    namespace Microsoft.AspNet.Identity
    {
      /// <summary>
      /// Used to validate an item
      /// 
      /// </summary>
      /// <typeparam name="T"/>
      public interface IIdentityValidator<in T>
      {
        /// <summary>
        /// Validate the item
        /// 
        /// </summary>
        /// <param name="item"/>
        /// <returns/>
        Task<IdentityResult> ValidateAsync(T item);
      }
    }
    

    然后在ApplicationUserManager 中将您自己的实现分配给属性UserValidator

    如果你真的需要这个,你可以通过反编译 Microsoft.AspNet.Identity.UserValidator 类并查看现有源代码并删除检查电子邮件来获取 UserValidator 的原始源代码。

    但是,我不确定框架的其余部分会如何对用户缺少电子邮件做出反应。可能你会在其他操作中遇到异常。

    【讨论】:

      【解决方案4】:

      在启动文件中,您可以通过访问 IdentityOptions 配置来禁用 RequireUniqueEmail 也可以在这里更改密码的复杂性,锁定,...

        services.Configure<IdentityOptions>(x =>
              {
                  x.User.RequireUniqueEmail = false;
      
                  //x.Password.RequireUppercase = false; => other condition for identity
      
              });
      

      您应该使用 Microsoft.AspnetCore.Identity,文档地址here

      谢谢@PBO,您还可以更改身份选项,如下所示

       services.AddDefaultIdentity<IdentityUser>(
                  options=> { 
                      options.SignIn.RequireConfirmedAccount = false;
                      options.User.RequireUniqueEmail = false;
                      options.Password.RequireUppercase = false;
                  })
                  .AddEntityFrameworkStores<BookShopDbContext>();
      

      【讨论】:

      • 您可以在 services.AddDefaultIdentity 中访问相同的功能
      【解决方案5】:

      如果有人还在为此苦苦挣扎……

      设置options.User.RequireUniqueEmail=true,创建自定义用户验证器并在注册Identity之前注册它。这将使电子邮件成为可选的,但仍要求它在输入时是唯一的。

      ConfigureServices(IServiceCollection 服务)中:

      services.AddTransient<IUserValidator<ApplicationUser>, OptionalEmailUserValidator<MonotypeIdentityUser>>();
      services.AddIdentity(...);
      

      自定义用户验证器类:

      public class OptionalEmailUserValidator<TUser> : UserValidator<TUser> where TUser : class
      {
          public OptionalEmailUserValidator(IdentityErrorDescriber errors = null) : base(errors)
          {
          }
      
          public override async Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user)
          {
              var result = await base.ValidateAsync(manager, user);
              
              if(!result.Succeeded && String.IsNullOrWhiteSpace(await manager.GetEmailAsync(user)))
              {
                  var errors = result.Errors.Where(e => e.Code != "InvalidEmail");
      
                  result = errors.Count() > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
              }           
      
              return result;
          }
      }
      

      【讨论】:

      • 很好的答案,你也可以做一个 services.AddIdentity().AddUserValidator>() 注入一个衬垫
      【解决方案6】:

      您可以通过编辑 App_Start 文件夹中的身份文件并将 RequireUniqueEmail 值更改为 False 以避免电子邮件验证器来创建没有电子邮件的用户帐户`

        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
              {
                  AllowOnlyAlphanumericUserNames = false,
                  RequireUniqueEmail = false,
              };
      

      `

      【讨论】:

        【解决方案7】:

        其实还有更好的办法。仅在您需要忽略它时更改验证,然后在完成后将其恢复。 (在这种情况下不要使用异步,因为可能需要更新另一个线程(?))

        // first create/update the identity!!! 
        user.PasswordHash = UserManager.PasswordHasher.HashPassword(model.Password); //hash and update directly
        
        // alter
        UserManager.UserValidator = new UserValidator<StoreUser>(UserManager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = false
        };
        
        var result = UserManager.Update(user);
        
        // restore... 
        UserManager.UserValidator = new UserValidator<StoreUser>(UserManager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        

        【讨论】:

        • 这是一个非常非常糟糕的主意。如果两个人同时更新他们的用户会发生什么? Race condition 就是这样。你为什么不像其他人建议的那样在启动时设置一次?
        • 如果我想将现在在 AspNetUsers 中找到的电子邮件及其相关字段存储在单独的表中怎么办?电话字段也一样?
        • @muybn,我设法将电话号码、电子邮件地址分开到 AccountContact 表中。它的工作量很大,除非您有特定的理由这样做,否则这是浪费时间。我遇到了很多错误,需要花费大量时间查看源代码才能了解发生了什么。最初我也删除了用户名,但恢复它只是为了让我的项目继续进行(我根据客户提供的内容填写电话号码或电子邮件)。
        猜你喜欢
        • 1970-01-01
        • 2022-08-17
        • 2019-11-27
        • 2017-07-22
        • 2017-03-30
        • 1970-01-01
        • 2015-02-06
        • 2015-07-20
        • 1970-01-01
        相关资源
        最近更新 更多