2011-06-27 27 views
14

Tôi đọc trên một số bài đăng, nhưng không thể tìm thấy ngay bây giờ trong MVC 3 nó không thực sự cần thiết để tạo ra một Validator, chỉ có thuộc tính. Điều này có đúng không? Tôi nói rằng tôi thấy nó khó hiểu rằng thuộc tính có IClientValidatable trên nó. Vậy lớp DataAnnotationsModelValidator làm gì nếu chú thích có tên tập lệnh phía máy khách (IClientValidatable) và khả năng xác thực (ValidationAttribute IsValid)?MVC 2 vs MVC 3 thuộc tính xác thực tùy chỉnh sử dụng DataAnnotationsModelValidatorProvider.RegisterAdapter

Sẽ thật tuyệt nếu tôi không phải đăng ký Thuộc tính với Trình xác thực trong toàn cầu. Điều này có thể được thực hiện? Tôi đã đọc một số lời khuyên xấu?

EDIT: Điều thú vị đủ Tôi vừa thử nghiệm nó bằng cách loại trừ trình xác thực, đặt tất cả logic trong IsValid và nó hoạt động tốt. Tôi đoán điều duy nhất có thể bị thiếu sẽ là bối cảnh của trình điều khiển, nhưng tôi không chắc rằng điều đó có ích trong việc xác thực hay không. IsValid có ValidationContext có ServiceContainer nếu tôi cần một dịch vụ. Bất kỳ bất lợi thực sự tôi không chọn lên ở đây?

EDIT 2: Tôi sẽ bắt đầu với một validator từ ví dụ này: http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx

Các thuộc tính:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private RequiredAttribute innerAttribute = new RequiredAttribute(); 
    public string DependentProperty { get; set; } 
    public object TargetValue { get; set; } 

    public RequiredIfAttribute(string dependentProperty, object targetValue) 
    { 
     this.DependentProperty = dependentProperty; 
     this.TargetValue = targetValue; 
    } 

    public override bool IsValid(object value) 
    { 
     return innerAttribute.IsValid(value); 
    } 

    public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "requiredifattribute" 
     }; 
     modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty); 
     yield return modelClientValidationRule; 
    } 
} 

Các Validator:

public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute> 
{ 
    public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     return base.GetClientValidationRules(); 
    } 

    public override IEnumerable<ModelValidationResult> Validate(object container) 
    { 
     var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty); 
     if (field != null) 
     { 
      var value = field.GetValue(container, null); 
      if ((value == null && Attribute.TargetValue == null) || 
       (value.Equals(Attribute.TargetValue))) 
      { 
       if (!Attribute.IsValid(Metadata.Model)) 
        yield return new ModelValidationResult { Message = ErrorMessage }; 
      } 
     } 
    } 
} 

Với mã hiện tại ở trên, tôi cần đăng ký trong tệp Global.asax.cs:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute), typeof(RequiredIfValidator)); 

Nhưng nếu tôi di chuyển tất cả mọi thứ vào chỉ thuộc tính, Tôi không phải đăng ký nó:

public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private RequiredAttribute innerAttribute = new RequiredAttribute(); 
    public string DependentProperty { get; set; } 
    public object TargetValue { get; set; } 

    public RequiredIfAttribute(string dependentProperty, object targetValue) 
    { 
     this.DependentProperty = dependentProperty; 
     this.TargetValue = targetValue; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty); 
     if (field != null) 
     { 
      var dependentValue = field.GetValue(validationContext.ObjectInstance, null); 
      if ((dependentValue == null && TargetValue == null) || 
       (dependentValue.Equals(TargetValue))) 
      { 
       if (!innerAttribute.IsValid(value)) 
        return new ValidationResult(ErrorMessage); 
      } 
     } 
     return ValidationResult.Success; 
    } 

    public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     ModelClientValidationRule modelClientValidationRule = new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
      ValidationType = "requiredifattribute" 
     }; 
     modelClientValidationRule.ValidationParameters.Add("requiredifattribute", DependentProperty); 
     yield return modelClientValidationRule; 
    } 
} 

Có một vấn đề với các bit cuối cùng của mã thay thế tất cả các mã khác? Tại sao tôi phải giữ lớp xác nhận?

+0

Nơi mà bạn đã đọc lời khuyên này? –

+0

Tôi ước mình có thể tìm thấy nó, nhưng tôi không thể. Nó đã được nhiều hơn một bình luận trên một số bài đăng. Bạn nghĩ gì về nó? – CrazyDart

+0

tại thời điểm này tôi không nghĩ bất cứ điều gì vì tôi vẫn đang cố gắng hiểu vấn đề/câu hỏi là gì.Tôi chỉ hy vọng sẽ thấy thêm một số ngữ cảnh, ví dụ mã cụ thể, v.v., đó là lý do tại sao tôi yêu cầu nguồn để cố gắng xem thêm ngữ cảnh như bạn chưa cung cấp đủ trong câu hỏi của bạn. Hy vọng rằng bạn sẽ cung cấp một số ví dụ mã cụ thể minh họa sự cố bạn đang gặp phải. –

Trả lời

10

CrazyDart,

Giao diện IClientValidatable được thêm vào MVC3.

Ví dụ thứ hai của bạn cho thấy việc sử dụng hợp lệ giao diện mới này. Bạn chính xác rằng nó không phải được đăng ký, và nó sẽ cung cấp các quy tắc phía khách hàng cần thiết để xác thực, cũng như thực hiện xác nhận hợp lệ phía máy chủ cần thiết.

Hãy tiếp tục, thưởng thức nó.

counsellorben

+1

Hóa ra bạn chính xác. Tôi sẽ sử dụng IClientValidatable, và tôi sẽ xem xét tốt trong khi làm điều đó. ;-) – CrazyDart

+1

Tôi nghĩ IClientValidatable vẫn yêu cầu người dùng thêm tập lệnh phía máy khách cho bộ điều hợp xác thực jquery và các phương thức xác thực theo sự hiểu biết của tôi về IClientValidatable. – afr0

0

Khi tôi sử dụng tùy chọn cuối cùng từ CrazyDart phần phía máy chủ hoạt động tốt trong MVC4.

Ngoại trừ tôi không thể xác thực phía máy khách để hoạt động. Nó không bao giờ kiểm tra một trường bắt buộc ở phía máy khách (mặc dù có một số thẻ được thêm vào).

Tôi cũng đã kiểm tra các bài viết trên blog 2 (1st là nguồn cảm hứng của người gửi) của Simon Ince về điều này: http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

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