如何一次使用验证属性定义一个属性,然后在多个视图模型中使用该属性?

时间:2019-02-13 08:20:36

标签: asp.net interface asp.net-mvc-5 data-annotations

我有许多用户帐户控制器,并为管理用户帐户而实现了视图模型。这些视图模型中的许多模型包含相同的属性(例如,电子邮件,用户名,名字,姓氏,密码),并带有相同的数据验证注释。我试图弄清楚如何(或什至有可能)将我的验证注释分成一个单独的接口/类,这样我只需要定义一次这些注释即可。最终目标是我不必重复验证批注(保持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从父视图模型中引用电子邮件地址。

这肯定是一个常见问题,我不知道如何搜索正确的答案,或者我只是没有把所有的点都联系在一起。

0 个答案:

没有答案