使用 DataAnnotations 比较两个模型属性

发布于 2024-10-16 11:57:31 字数 739 浏览 5 评论 0原文

我将如何编写一个比较两个字段的自定义 ValidationAttribute?这就是常见的“输入密码”、“确认密码”场景。我需要确保两个字段相等并保持一致,我想通过 DataAnnotations 实现验证。

因此,在伪代码中,我正在寻找一种方法来实现如下所示的内容:

public class SignUpModel
{
    [Required]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Required]
    [Display(Name = "Re-type Password")]
    [Compare(CompareField = Password, ErrorMessage = "Passwords do not match")]
    public string PasswordConfirm { get; set; }
}

public class CompareAttribute : ValidationAttribute
{
    public CompareAttribute(object propertyToCompare)
    {
        // ??
    }

    public override bool IsValid(object value)
    {
        // ??
    }
}

所以问题是,如何编码 [Compare] ValidationAttribute?

How would I go about writing a custom ValidationAttribute that compares two fields? This is the common "enter password", "confirm password" scenario. I need to be sure the two fields are equal and to keep things consistent, I want to implement the validation via DataAnnotations.

So in pseudo-code, I'm looking for a way to implement something like the following:

public class SignUpModel
{
    [Required]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Required]
    [Display(Name = "Re-type Password")]
    [Compare(CompareField = Password, ErrorMessage = "Passwords do not match")]
    public string PasswordConfirm { get; set; }
}

public class CompareAttribute : ValidationAttribute
{
    public CompareAttribute(object propertyToCompare)
    {
        // ??
    }

    public override bool IsValid(object value)
    {
        // ??
    }
}

So the question is, how do I code the [Compare] ValidationAttribute?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

指尖微凉心微凉 2024-10-23 11:57:31

确保您的项目引用 system.web.mvc v3.xxxxx。

那么你的代码应该是这样的

using System.Web.Mvc;




[Required(ErrorMessage = "This field is required.")]    
public string NewPassword { get; set; }

[Required(ErrorMessage = "This field is required.")]
[Compare(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
public string RepeatPassword { get; set; }

Make sure that your project references system.web.mvc v3.xxxxx.

Then your code should be something like this:

using System.Web.Mvc;

.
.
.
.

[Required(ErrorMessage = "This field is required.")]    
public string NewPassword { get; set; }

[Required(ErrorMessage = "This field is required.")]
[Compare(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
public string RepeatPassword { get; set; }
难忘№最初的完美 2024-10-23 11:57:31

ASP.NET MVC 3 Framework 中有一个 CompareAttribute 可以执行此操作。如果您使用 ASP.NET MVC 2 并面向 .Net 4.0,那么您可以查看 ASP.NET MVC 3 源代码中的实现。

There is a CompareAttribute in the ASP.NET MVC 3 Framework that does this. If you are using ASP.NET MVC 2 and targeting .Net 4.0 then you could look at the implementation in the ASP.NET MVC 3 source code.

吾家有女初长成 2024-10-23 11:57:31

这是达林答案的较长版本:

public class CustomAttribute : ValidationAttribute
{    
    public override bool IsValid(object value)
    {
        if (value.GetType() == typeof(Foo))
        {
           Foo bar = (Foo)value;
           //compare the properties and return the result
        }

        throw new InvalidOperationException("This attribute is only valid for Foo objects");
    }
}

和用法:

[MetadataType(typeof(FooMD))]
public partial class Foo
{
     ... functions ...
}

[Custom]
public class FooMD
{
     ... other data annotations ...
}

错误将显示在 @Html.ValidationSummary(false)

This is a longer version of Darin's answer:

public class CustomAttribute : ValidationAttribute
{    
    public override bool IsValid(object value)
    {
        if (value.GetType() == typeof(Foo))
        {
           Foo bar = (Foo)value;
           //compare the properties and return the result
        }

        throw new InvalidOperationException("This attribute is only valid for Foo objects");
    }
}

and usage:

[MetadataType(typeof(FooMD))]
public partial class Foo
{
     ... functions ...
}

[Custom]
public class FooMD
{
     ... other data annotations ...
}

The error will display in @Html.ValidationSummary(false)

零度℉ 2024-10-23 11:57:31

您可以拥有自定义验证属性并将其应用于模型而不是单个属性。您可以看一下以下示例

You could have a custom validation attribute and apply it on the model and not on individual properties. Here's an example you might take a look at.

紫﹏色ふ单纯 2024-10-23 11:57:31

如果你们正在使用 MVC 4,请尝试此代码..它将解决您的错误..

请创建一个元数据类,而不是在部分类实现确认电子邮件属性中。检查下面的代码以获取更多详细信息。

using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using StringlenghtMVC.Comman;
    using System.Web.Mvc;

using System.Collections;

    [MetadataType(typeof(EmployeeMetaData))] //here we call metadeta class
    public partial class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public Nullable<int> Age { get; set; }
        public string Gender { get; set; }
        public Nullable<System.DateTime> HireDate { get; set; }

       //[CompareAttribute("Email")]
        public string ConfirmEmail { get; set; }
    }

    public class EmployeeMetaData
    {
        [StringLength(10, MinimumLength = 5)]
        [Required]
        //[RegularExpression(@"(([A-za-Z]+[\s]{1}[A-za-z]+))$", ErrorMessage = "Please enter Valid Name")]
        public string Name { get; set; }

        [Range(1, 100)]
        public int Age { get; set; }
        [CurrentDate]
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        public DateTime HireDate { get; set; }

        //[RegularExpression(@"^[\w-\._\%]+@(?:[\w]{2,6}$")]
        public string Email { get; set; }

        [System.Web.Mvc.CompareAttribute("Email")]
        public string ConfirmEmail { get; set; }


    }

if you guys are using MVC 4 please try this code .. it will solve your error..

please make one Metadataclass than in partial class impliment comfirmemail properties . check the below code for more details.

using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using StringlenghtMVC.Comman;
    using System.Web.Mvc;

using System.Collections;

    [MetadataType(typeof(EmployeeMetaData))] //here we call metadeta class
    public partial class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public Nullable<int> Age { get; set; }
        public string Gender { get; set; }
        public Nullable<System.DateTime> HireDate { get; set; }

       //[CompareAttribute("Email")]
        public string ConfirmEmail { get; set; }
    }

    public class EmployeeMetaData
    {
        [StringLength(10, MinimumLength = 5)]
        [Required]
        //[RegularExpression(@"(([A-za-Z]+[\s]{1}[A-za-z]+))$", ErrorMessage = "Please enter Valid Name")]
        public string Name { get; set; }

        [Range(1, 100)]
        public int Age { get; set; }
        [CurrentDate]
        [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
        public DateTime HireDate { get; set; }

        //[RegularExpression(@"^[\w-\._\%]+@(?:[\w]{2,6}$")]
        public string Email { get; set; }

        [System.Web.Mvc.CompareAttribute("Email")]
        public string ConfirmEmail { get; set; }


    }
别把无礼当个性 2024-10-23 11:57:31

对于未来关注这个问题的人,我试图编写一个验证属性,如果对象的属性是某个值,它将评估正则表达式。就我而言,如果地址是送货地址,我不希望启用邮政信箱,所以这就是我想到的:

用法

[Required]
public EAddressType addressType { get; set; } //Evaluate Validation attribute against this

[EvaluateRegexIfPropEqualsValue(Constants.NOT_PO_BOX_REGEX, "addressType", EAddressType.Shipping, ErrorMessage = "Unable to ship to PO Boxes or APO addresses")]
public String addressLine1 { get; set; }

这是验证属性的代码:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class EvaluateRegexIfPropEqualsValue : ValidationAttribute
{
    Regex _regex;
    string _prop;
    object _targetValue;

    public EvaluateRegexIfPropEqualsValue(string regex, string prop, object value)
    {
        this._regex = new Regex(regex);
        this._prop = prop;
        this._targetValue = value;
    }

    bool PropertyContainsValue(Object obj)
    {
        var propertyInfo = obj.GetType().GetProperty(this._prop);
        return (propertyInfo != null && this._targetValue.Equals(propertyInfo.GetValue(obj, null)));
    }

    protected override ValidationResult IsValid(object value, ValidationContext obj)
    {
        if (this.PropertyContainsValue(obj.ObjectInstance) && value != null && !this._regex.IsMatch(value.ToString()))
        {
            return new ValidationResult(this.ErrorMessage);
        }
        return ValidationResult.Success;
    }
}

For future people looking at this issue, I was trying to write a validation attribute that would evaluate a regex if an object's property were a certain value. In my case, if an address was a shipping address, I didn't want PO Boxes enabled, so this is what I came up with:

Usage

[Required]
public EAddressType addressType { get; set; } //Evaluate Validation attribute against this

[EvaluateRegexIfPropEqualsValue(Constants.NOT_PO_BOX_REGEX, "addressType", EAddressType.Shipping, ErrorMessage = "Unable to ship to PO Boxes or APO addresses")]
public String addressLine1 { get; set; }

And here's the code for the validation attribute:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class EvaluateRegexIfPropEqualsValue : ValidationAttribute
{
    Regex _regex;
    string _prop;
    object _targetValue;

    public EvaluateRegexIfPropEqualsValue(string regex, string prop, object value)
    {
        this._regex = new Regex(regex);
        this._prop = prop;
        this._targetValue = value;
    }

    bool PropertyContainsValue(Object obj)
    {
        var propertyInfo = obj.GetType().GetProperty(this._prop);
        return (propertyInfo != null && this._targetValue.Equals(propertyInfo.GetValue(obj, null)));
    }

    protected override ValidationResult IsValid(object value, ValidationContext obj)
    {
        if (this.PropertyContainsValue(obj.ObjectInstance) && value != null && !this._regex.IsMatch(value.ToString()))
        {
            return new ValidationResult(this.ErrorMessage);
        }
        return ValidationResult.Success;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文