我有许多用户帐户控制器,并为管理用户帐户而实现了视图模型。这些视图模型中的许多模型包含相同的属性(例如,电子邮件,用户名,名字,姓氏,密码),并带有相同的数据验证注释。我试图弄清楚如何(或什至有可能)将我的验证注释分成一个单独的接口/类,这样我只需要定义一次这些注释即可。最终目标是我不必重复验证批注(保持DRY不变),并且服务器端和客户端验证都可以工作。
我真的很接近,但是无法越过终点线。考虑以下两种视图模型:
[MetadataType(typeof(IRegisterViewModel))]
public class RegisterViewModel : IRegisterViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
[MetadataType(typeof(IAccountPassword))]
public class ChangePasswordViewModel : IAccountPassword
{
// this version is for already authenticated users that want to change their password
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
具有以下注释接口:
public interface IRegisterViewModel : IAccountName, IAccountEmail, IAccountUserName, IAccountPassword { }
public interface IAccountEmail
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid Email address")]
[Display(Name = "Email")]
string Email { get; set; }
}
public interface IAccountName
{
[Required]
[MinLength(2, ErrorMessage = "First Name must be at least 2 letters")]
[MaxLength(50, ErrorMessage = "First Name is too long")]
[Display(Name = "First Name")]
string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is required")]
[MinLength(2, ErrorMessage = "Last Name must be at least 2 letters")]
[MaxLength(50, ErrorMessage = "Last Name is too long")]
[Display(Name = "Last Name")]
string LastName { get; set; }
}
public interface IAccountPassword
{
[Required(ErrorMessage = "Password is required")]
[StringLength(100, ErrorMessage = "Password must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
string ConfirmPassword { get; set; }
}
当我使用由多个接口组成的接口时(如IRegisterViewModel
),数据验证不起作用(甚至没有连接起来)。但是,当我使用IAccountPassword
(仅实现一个接口)时,数据验证确实起作用。
这些只是两个示例...我有更多的帐户控制器/模型/视图用于管理用户帐户,其中许多使用一些通用属性组合。一次定义这些似乎是一种普遍的愿望,而不是通过在多个视图模型上定义它们来重复自己(并且必须在视图模型之间维护对这些定义的更新)。
我还看到了关于SO的其他几篇文章,人们试图做到基本相同。通常,问题/答案仅涉及单个继承,而不涉及我尝试的多个继承。其他人已有很多年历史了,并且/或者被标记了较旧的MVC版本(所以我不知道它们是否有效)。无论如何,我还没有发现任何有效的方法。
This was an interesting question/answer approach由一个或多个“子”视图模型组成所需的视图模型。我想如果没有其他结果,我可以尝试这种方法,但是创建具有单个属性的视图模型似乎很笨拙且容易出错,然后必须使用Model.Email.Email
从父视图模型中引用电子邮件地址。
这肯定是一个常见问题,我不知道如何搜索正确的答案,或者我只是没有把所有的点都联系在一起。