4

我在这里尝试做两件事:

1.将电子邮件字段添加到(默认)UserProfile 表。奇迹般有效。用户可以注册用户名和电子邮件。

2.将登录更改为使用电子邮件而不是用户名,这也很有效。

这是问题所在。以上仅在我将它们分开时才有效,只要我同时使用它们,注册过程就会失败并显示以下错误消息:

Cannot insert the value NULL into column 'UserName', table 'opdb.dbo.UserProfile'; column does not allow nulls. INSERT fails.

WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email 
}); 
WebSecurity.Login(model.Email, model.Password);

我或多或少遵循 此处找到的指南 在评论部分我看到其他人有同样的问题,但是,解决方案不是设置 UserName 字段以允许空值,如回复中所述。

奇怪的是,只要我不同时使用两者,一切都可以正常工作。有任何想法吗?这让我发疯!

提前致谢

编辑:可能是数据库中列的顺序吗?用于标识的字段必须是表中的第一列?那么,如果我想要电子邮件作为身份,需要成为表格中的第一列?

4

2 回答 2

5

这不是列顺序。我认为你没有WebSecurity.InitializeDatabaseConnection正确设置你的。听起来当您添加电子邮件字段时,它被视为电子邮件字段(而不是用户的自然键),而当您更改登录名以使用电子邮件时,您实际上是在将电子邮件插入 UserName 列?

无论哪种方式,工作都很简单。假设您已经在数据库中有您的电子邮件列并且您正在使用标准 Internet 应用程序模板,请执行以下操作:

  1. 更改您的UserProfile模型以添加Email属性,对 执行相同操作RegisterModel并将Login模型从更改UserNameEmail
  2. 更新 InitializeSimpleMembershipAttribute以使用电子邮件而不是UserName作为用户的自然键
  3. 更新AccountController LoginRegister操作,以便您在注册时捕获用户名和电子邮件,并在登录时使用电子邮件
  4. 更新视图

因此,要进行的实际更改是:

  • 模型/AccountModels.cs 更改
    • class UserProfile: 添加属性public string Email { get; set; }
    • class LoginModel:将属性名称从更改UserNameEmail
    • class RegisterModel:添加属性public string Email { get; set; }并将其属性设置为Required,设置Display(Name等(如果您也想强制执行,则为最大长度
  • AccountController变化
    • Login方法:
      • 换成model.UserNamemodel.Emailif (ModelState.IsValid && WebSecurity.Login(model.UserName ...
    • Register方法:
      • 更改WebSecurity.CreateUserAndAccount(model.UserName, model.Password);WebSecurity.CreateUserAndAccount(model.Email, model.Password, new { UserName = model.UserName });
      • 编辑 - 错过了一个变化: 更改WebSecurity.Login(model.UserName, model.Password);WebSecurity.Login(model.Email, model.Password);
  • Filters/InitializeSimpleMembershipAttribute.cs 更改
    • 更改"UserName""Email"_WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
  • 视图/帐户/Login.cshtml
    • 改变m.UserNameto的三种用法m.Email
  • 视图/帐户/Register.cshtml
    • 复制并粘贴 UserName<li>部分并将重复项更改 m.UserNamem.Email

在 vanilla Internet Application MVC 4 项目中,这些更改将完美运行(在真正的 vanilla 项目中,如果您想使用这些更改并且您没有编辑数据库以添加电子邮件列,则可能必须应用迁移)。

于 2013-05-13T21:09:25.337 回答
2

我不确定 Andy Browns 的建议是否有效,因为命名空间 WebMatrix.WebData 中的 WebSecurity 引用将因此无法正常工作。他们专门查看 UserName 字段来执行他们的操作。我可能是错的,但这是我的看法。如果您想要一个单独的字段,请创建另一个用户名字段(名称)并运行您自己的代码来更新它以反映给用户。

我选择设置一个注册视图,将 UserName 重命名为 User Email

<li>
@Html.Label("Email Address:")
@Html.TextBoxFor(m => m.UserName)
</li>

然后在登录和注册模型中只需要使用以下电子邮件格式输入用户名:

[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress]
[Display(Name = "UserEmail")]
public string UserName { get; set; } 

也许太简单了,但它对我有用。

于 2013-09-07T20:17:52.577 回答