如何更新格式与定义模型不同的密码?我收到 DbEntityValidationException
How do I update a password that's in a different format from the defined model? I'm getting DbEntityValidationException
问题
- 我的代码优先模型有预定义的
[StringLength()]
和 [RegularExpression()]
约束。
[StringLength()]
要求是8-16个字符
- 密码的
[RegularExpression()]
约束与加密密码采用 不同的 格式。
- 密码在被推入数据库之前被加密。
- 加密后的密码长度为 70 个字符,高于模型中定义的 8-16 个字符的限制。
- 我需要使用
e.Encrypt()
,这意味着我不能使用默认的 ASP.NET 哈希算法。
我到处搜索,但还没有找到正确的答案。
我的代码
我有一个允许用户注册帐户的功能。它看起来像这样:
[HttpPost]
public ActionResult Register([Bind(Include="Username,Password,EmailAddress")] UserModel user)
{
if (TryUpdateModel(user))
{
// Set password to a different format than Model's designated Regex
user.Password = e.Encrypt(user.Password);
context.Entry(user).State = EntityState.Added;
context.SaveChanges();
return RedirectToAction("Login", "Account");
}
return View();
}
在我的 UserModel.cs
文件中,我有以下约束:
[Required]
[DataType(DataType.Password)]
[StringLength(16, MinimumLength = 8, ErrorMessage = "Must be between 8 and 16 characters.")]
[RegularExpression("^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]", ErrorMessage = ErrorMessage_PasswordRegex)]
public string Password { get; set; }
同样,散列密码的格式完全不同。因此,我无法更新它,因为它会抛出 DbEntityValidationException
。这个[RegularExpression()]
是针对用户密码的格式。我需要能够绕过或暂停密码的 Regex 约束。
我做了什么来补救这个问题
我删除了 [RegularExpression()]
要求,并将 [StringLength()]
提高到 70,这是我的密码哈希的长度。
但是,我不想让用户输入 70 个字符的文本。这似乎是一种廉价的 hack,我觉得应该有更好的方法来做到这一点。有什么想法吗?
这是一个例子:
我们对用户输入的要求与我们的数据库要求不同。我们可能需要更多的用户输入,我们将以编程方式对其进行处理。
EF 模型
public class UserModel()
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
[Required, StringLength(70)]
public string Password { get; set; }
}
下面是我们用来捕获用户输入的class
public class UserViewModel()
{
[Required]
public string Name { get; set; }
[Required]
[RegularExpression("^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]", ErrorMessage = ErrorMessage_PasswordRegex)]
public string Password { get; set; }
[Required]
public string ConfirmPassword { get; set; }
}
现在我们转换和映射值。
用户将不知道 Id
使用什么,数据库不需要 ConfirmPassword
。我们还可以将用户最初输入的内容转换为密码。
[HttpPost]
public ActionResult Register(UserViewModel model)
{
if ((ModelState.IsValid) &&
(model.Password == model.ConfirmPassword))
{
// map to EF model
var user = new UserModel
{
Name = model.Name,
Password = e.encrypt(model.Password) // transform, encrypt, whatever
};
db.Users.Add(user); // use EF model to persist
...
return RedirectToAction("Login", "Account");
}
return(model);
}
问题
- 我的代码优先模型有预定义的
[StringLength()]
和[RegularExpression()]
约束。 [StringLength()]
要求是8-16个字符- 密码的
[RegularExpression()]
约束与加密密码采用 不同的 格式。- 密码在被推入数据库之前被加密。
- 加密后的密码长度为 70 个字符,高于模型中定义的 8-16 个字符的限制。
- 我需要使用
e.Encrypt()
,这意味着我不能使用默认的 ASP.NET 哈希算法。
我到处搜索,但还没有找到正确的答案。
我的代码
我有一个允许用户注册帐户的功能。它看起来像这样:
[HttpPost]
public ActionResult Register([Bind(Include="Username,Password,EmailAddress")] UserModel user)
{
if (TryUpdateModel(user))
{
// Set password to a different format than Model's designated Regex
user.Password = e.Encrypt(user.Password);
context.Entry(user).State = EntityState.Added;
context.SaveChanges();
return RedirectToAction("Login", "Account");
}
return View();
}
在我的 UserModel.cs
文件中,我有以下约束:
[Required]
[DataType(DataType.Password)]
[StringLength(16, MinimumLength = 8, ErrorMessage = "Must be between 8 and 16 characters.")]
[RegularExpression("^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]", ErrorMessage = ErrorMessage_PasswordRegex)]
public string Password { get; set; }
同样,散列密码的格式完全不同。因此,我无法更新它,因为它会抛出 DbEntityValidationException
。这个[RegularExpression()]
是针对用户密码的格式。我需要能够绕过或暂停密码的 Regex 约束。
我做了什么来补救这个问题
我删除了 [RegularExpression()]
要求,并将 [StringLength()]
提高到 70,这是我的密码哈希的长度。
但是,我不想让用户输入 70 个字符的文本。这似乎是一种廉价的 hack,我觉得应该有更好的方法来做到这一点。有什么想法吗?
这是一个例子:
我们对用户输入的要求与我们的数据库要求不同。我们可能需要更多的用户输入,我们将以编程方式对其进行处理。
EF 模型
public class UserModel()
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
[Required, StringLength(70)]
public string Password { get; set; }
}
下面是我们用来捕获用户输入的class
public class UserViewModel()
{
[Required]
public string Name { get; set; }
[Required]
[RegularExpression("^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]", ErrorMessage = ErrorMessage_PasswordRegex)]
public string Password { get; set; }
[Required]
public string ConfirmPassword { get; set; }
}
现在我们转换和映射值。
用户将不知道 Id
使用什么,数据库不需要 ConfirmPassword
。我们还可以将用户最初输入的内容转换为密码。
[HttpPost]
public ActionResult Register(UserViewModel model)
{
if ((ModelState.IsValid) &&
(model.Password == model.ConfirmPassword))
{
// map to EF model
var user = new UserModel
{
Name = model.Name,
Password = e.encrypt(model.Password) // transform, encrypt, whatever
};
db.Users.Add(user); // use EF model to persist
...
return RedirectToAction("Login", "Account");
}
return(model);
}