2011-02-08 26 views
31

Làm cách nào để tôi viết về một ValidationAttribute tùy chỉnh so sánh hai trường? Đây là trường hợp "nhập mật khẩu" phổ biến, "xác nhận mật khẩu". Tôi cần đảm bảo hai trường đều bình đẳng và giữ cho mọi thứ nhất quán, tôi muốn triển khai xác thực thông qua DataAnnotations.Sử dụng DataAnnotations để so sánh hai thuộc tính mô hình

Vì vậy, trong pseudo-code, Tôi đang tìm kiếm một cách để thực hiện một cái gì đó như sau:

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) 
    { 
     // ?? 
    } 
} 

Vậy câu hỏi là, làm thế nào để viết mã [So sánh] ValidationAttribute?

Trả lời

25

Có một CompareAttribute trong ASP.NET MVC 3 Framework thực hiện việc này. Nếu bạn đang sử dụng ASP.NET MVC 2 và nhắm mục tiêu .Net 4.0 thì bạn có thể xem xét việc thực hiện trong mã nguồn ASP.NET MVC 3.

3

Bạn có thể có thuộc tính xác thực tùy chỉnh và áp dụng thuộc tính đó trên mô hình chứ không phải thuộc tính cá nhân. Đây là số example bạn có thể xem.

7

Đây là một phiên bản dài hơn câu trả lời Darin của:

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"); 
    } 
} 

và cách dùng:

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

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

Các lỗi sẽ hiển thị trong @Html.ValidationSummary(false)

42

Hãy chắc chắn rằng tài liệu tham khảo dự án của bạn system.web. mvc v3.xxxxx.

Sau đó, mã của bạn nên có một cái gì đó như thế này:

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; } 
+2

Trong trường hợp này, bạn có thể tự lưu thuộc tính Bắt buộc cho thuộc tính thứ hai vì bạn đã thực thi so sánh với thuộc tính đầu tiên thực tế bắt buộc. –

+1

Lưu ý rằng, với C# 6.0, bây giờ có thể sử dụng từ khóa 'nameof', thay vì sử dụng" chuỗi ma thuật "làm tên thuộc tính.Điều này làm cho việc tái cấu trúc tốt hơn/dễ dàng hơn của bất kỳ thuộc tính liên quan nào, vì nó đang sử dụng tên thuộc tính gõ mạnh, thay vào đó (và tiết kiệm cho bạn phải nhớ cập nhật chuỗi ma thuật (như tôi đã thực hiện một vài lần)). Thêm vào đó, trình biên dịch sẽ bị lỗi nếu bạn đã từng bỏ lỡ một, bằng cách nào đó - do đó làm cho nó "dễ dàng". Ví dụ sử dụng theo câu trả lời của @ Janx: '[CompareAttribute (nameof (NewPassword), ErrorMessage =" Mật khẩu không khớp. ")]' –

0

Đối với những người trong tương lai xem xét vấn đề này, tôi đã cố gắng viết thuộc tính xác thực sẽ đánh giá regex nếu thuộc tính của đối tượng là một giá trị nhất định. Trong trường hợp của tôi, nếu một địa chỉ là một địa chỉ vận chuyển, tôi không muốn PO Hộp kích hoạt, vì vậy đây là những gì tôi đã đưa ra:

Cách sử dụng

[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; } 

Và đây là đoạn code cho thuộc tính validation :

[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; 
    } 
} 
2

nếu các bạn đang sử dụng MVC 4 hãy thử mã này .. nó sẽ giải quyết lỗi của bạn ..

hãy một Metadataclass hơn trong phần lớp impliment comfirmemail p roperties. kiểm tra mã dưới đây để biết thêm chi tiết.

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-\._\%][email protected](?:[\w]{2,6}$")] 
     public string Email { get; set; } 

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


    } 
Các vấn đề liên quan