4

有没有办法在 ASP.Net MVC 4 的视图中用作模型的类内部实现数据域(在属性级别)的想法?

考虑这段代码:

public class LoginProfileModel {

    [DisplayName("Login ID")]
    [Required(ErrorMessage = "Login ID is required.")]
    public string LogonID { get; set; }

    [DisplayName("Password")]
    [Required(ErrorMessage = "Password cannot be blank.")]
    [StringLength(20, MinimumLength = 3)]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

这是 ASP.Net MVC 4 中的 LoginProfileModel。它使用各种元数据/数据注释,以便我可以使用以下代码创建一个干净的视图:

@model myWebSite.Areas.People.Models.LoginProfileModel

@using ( Html.BeginForm( "Index" , "Login" ) ) {
    @Html.ValidationSummary()
    @Html.EditorForModel()
    <input type="submit" value="Login" />
}

我在多个视图中使用“登录 ID”和“密码”的概念,因此在多个视图模型中。我希望能够定义密码使用的属性,或者可能是密码本身及其所有数据注释在一个位置,以便我可以在需要时重用所有这些定义,而不是每次使用时都重新指定它们:

    [DisplayName("Password")]
    [Required(ErrorMessage = "Password cannot be blank.")]
    [StringLength(20, MinimumLength = 3)]
    [DataType(DataType.Password)]
    public string Password { get; set; }

这有可能吗?

4

3 回答 3

3

以下属性会影响您的视图的验证过程。

[Required(ErrorMessage = "Password cannot be blank.")]
[StringLength(20, MinimumLength = 3)]

对于 Validation 属性,您可以像这样创建一个类:

public class PasswordRuleAttribute : ValidationAttribute
    {    
        public override bool IsValid(object value)
        {

            if (new RequiredAttribute { ErrorMessage = "Password cannot be blank." }.IsValid(value) && new StringLengthAttribute(20) { MinimumLength=3 }.IsValid(value) )
                return true;

            return false;
        }
    }

您可以按如下方式使用它:

[PasswordRule]
public string Password{get;set;}

您提到的其他两个属性是直接从Attribute类派生的,我认为没有办法将它们合并为一个属性。

我会尽快更新您的编辑。

所以现在我们剩下:

[DisplayName("Password")]
[DataType(DataType.Password)]
[PasswordRule]
public string Password{get;set;}

编辑:

根据这篇文章:Composite Attribute,无法合并属性。

于 2013-11-02T19:43:34.207 回答
1

您可以使用伙伴类来执行此操作,该类为您的视图模型提供元数据。像这样:

public partial class LogonMetaData
{
    [DisplayName("Login ID")]
    [Required(ErrorMessage = "Login ID is required.")]
    public string LogonID { get; set; }

    [DisplayName("Password")]
    [Required(ErrorMessage = "Password cannot be blank.")]
    [StringLength(20, MinimumLength = 3)]
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

然后你的视图模型:

using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(LogonMetaData))]
public partial class FirstViewModel
{
    public string LogonID { get; set; }
    public string Password { get; set; }
}

using System.ComponentModel.DataAnnotations;

[MetadataType(typeof(LogonMetaData))]
public partial class SecondViewModel
{
    public string LogonID { get; set; }
    public string Password { get; set; }
}

注意partial在类定义中的使用。这就是允许这种方法起作用的原因。一个警告,除了 DRY 的明显问题之外,我认为元数据类必须与您的视图模型位于同一命名空间中,否则它会抱怨。除此之外,这应该做你想要的。

于 2013-11-02T20:21:23.007 回答
0

作为 John H 回答的推论,您可以只使用继承并使那些具有“LogonId 和密码的想法”的视图模型从该基本视图模型继承。这将解决上一个答案中提到的元数据问题。

      public class LoginProfileModel {

        [DisplayName("Login ID")]
        [Required(ErrorMessage = "Login ID is required.")]
        public string LogonID { get; set; }

        [DisplayName("Password")]
        [Required(ErrorMessage = "Password cannot be blank.")]
        [StringLength(20, MinimumLength = 3)]
        [DataType(DataType.Password)]
        public string Password { get; set; }
    }

    public SomeOtherClassThatNeedsLoginInfo : LoginProfileModel{

         public string Property {get;set;}
}

现在在 SomeOtherClassThatNeedsLoginInfo 中,您可以使用这些属性及其相关的 DataAnnotations。

另一个想法是将 LoginInfo 作为属性传递给您的其他视图模型。

public SomeOtherClassThatNeedsLoginInfo{

             public string Property {get;set;}

             public LoginProfileModel LoginModel {get;set;}
    }
于 2013-11-03T23:47:06.460 回答