【发布时间】:2011-10-20 17:05:28
【问题描述】:
我使用的是 ASP.NET MVC 3 和 Entity Framework 4.1 Code First。
假设我有一个User 实体:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
在我的UserController 中编辑它时,我想添加一个PasswordConfirmation 字段并验证PasswordConfirmation == Password
1。按组成
我的第一次尝试是:
public class EditUserModel
{
[Required]
public User User { get; set; }
[Compare("User.Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
在这种情况下,客户端验证有效但(编辑:客户端验证工作是巧合。)不起作用和服务器端验证失败并显示以下消息:找不到名为 User.Password 的属性
编辑:我认为在这种情况下,最好的解决方案是创建一个自定义CompareAttribute
实现IValidatableObject
public class EditUserModel : IValidatableObject
{
[Required]
public User User { get; set; }
public string PasswordConfirmation { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(this.PasswordConfirmation != this.User.Password)
return new[] { new ValidationResult("Passwords don't match", new[] { "PasswordConfirmation " }) };
return new ValidationResult[0];
}
}
在这种情况下,服务器端验证工作,但客户端验证不再工作。实现IClientValidatable 似乎有点太复杂了,在这种情况下我更喜欢不进行客户端验证。
2。通过继承
public class EditUserModel : User
{
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
当尝试使用 EF 直接保存 EditUserModel 时,它不起作用,我收到一些关于 EditUserModel 元数据的错误消息,所以我使用 AutoMapper 从 User 转换到EditUserModel 和向后。
这个解决方案有效,但它更复杂,因为我必须从模型转换为视图模型并向后转换。
3。通过复制
(由 Malte Clasen 建议)
视图模型将具有模型的所有属性以及其他属性。 AutoMapper 可用于从一种转换到另一种。
public class EditUserModel {
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string ConfirmPassword { get; set; }
}
这是我最不喜欢的解决方案,因为代码重复(DRY)
问题
这种情况下继承、组合和重复的优缺点是什么?
有没有一种简单的方法可以同时进行客户端和服务器端验证,而无需将模型转换为视图模型并向后转换?
【问题讨论】:
标签: c# .net asp.net-mvc architecture