2013-01-11 9 views
5

Làm cách nào để tạo thuộc tính xác thực tùy chỉnh với xác thực phía máy khách mà không triển khai IClientValidatable?ASP.NET MVC: Triển khai xác thực phía máy khách với thuộc tính mà không IClientValidatable

Làm cách nào để System.ComponentModel.DataAnnotations.RequiredAttribute phía khách hàng xác thực?

Lý do để làm điều này là vì tôi đang sử dụng các đối tượng từ các lớp trong một dự án khác làm mô hình trong quan điểm của tôi và tôi không muốn thêm tham chiếu System.Web.MVC vào dự án đó.

EDIT để thêm thông tin:

  • Tôi biết rằng IClientValidatable được sử dụng để thêm thuộc tính tùy chỉnh để HTML để được sử dụng sau bằng cách xác nhận không phô trương.

  • Tôi biết tôi cần thêm mã javascript để thực hiện xác thực trong khách hàng.

Điều tôi không biết là cách sử dụng thông tin từ thuộc tính xác thực tùy chỉnh để thêm thuộc tính cần thiết vào HTML để xác thực không hoạt động.

Đây là thuộc tính xác nhận tùy chỉnh của tôi:

public class RequiredGuidAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     Guid? guidValue = value as Guid?; 

     if (guidValue == null) 
      return false; 

     return guidValue != Guid.Empty; 
    } 
} 

Đây là tài sản của tôi với thuộc tính áp dụng:

[RequiredGuid(ErrorMessageResourceType = typeof(ClientOrderResources), ErrorMessageResourceName = "RequiredShippingMethod")] 
    public Guid ShippingMethodId 
    { 
     get { return GetProperty(ShippingMethodIdProperty); } 
     set { SetProperty(ShippingMethodIdProperty, value); } 
    } 

Và cuối cùng tôi vẽ một đầu vào ẩn cho tài sản trong quan điểm cho rằng sử dụng Html.HiddenFor.

Bây giờ, làm thế nào tôi có thể nhận được thông báo lỗi từ thuộc tính để áp dụng nó vào HTML? Tôi có nên tự làm bằng cách sử dụng Reflection hoặc có cách nào tốt hơn không?

Và sau đó làm cách nào tôi có thể yêu cầu Html.HiddenFor sử dụng thông tin đó để thêm các thuộc tính cần thiết vào HTML?

Trả lời

0

Bạn không thể có xác thực tùy chỉnh trên máy khách trừ khi bạn triển khai IClientValidatable. Và cho rằng bạn cũng cần phải thêm kịch bản khách hàng là tốt.

http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvccustomvalidation_topic3.aspx

+0

Tôi xin lỗi nhưng nó phải là một cách, bởi vì các thuộc tính từ DataAnnotations được công nhận bởi những người trợ giúp html và họ xuất html với các thuộc tính cần thiết để xác thực khách hàng. Tôi biết rằng tôi sẽ phải thêm tập lệnh của khách hàng và đó không phải là một vấn đề. – Marques

0

Có thể, tôi tìm thấy bài viết này về cách để làm điều đó: http://xhalent.wordpress.com/2011/05/12/custom-unobstrusive-jquery-validation-in-asp-net-mvc-3-using-dataannotationsmodelvalidatorprovider/

về cơ bản bạn phải tạo một DataAnnotationsModelValidator về khách hàng của bạn một đăng ký nó trong Application_Start().

Và đừng quên rằng bạn vẫn phải viết Javascript để xác thực phía ứng dụng khách.

5

Chúng tôi đã gặp sự cố tương tự. Chúng tôi có một mô hình mà chúng tôi sử dụng để tạo tài khoản của mình sử dụng IClientValidatable trên các thuộc tính tùy chỉnh của nó. Tuy nhiên, chúng tôi đã tạo quy trình tạo tài khoản hàng loạt nằm bên ngoài trang web mà chúng tôi không thể tham chiếu System.Web.Mvc. Bởi vì điều này, khi chúng tôi gọi là Validator.TryValidateObject, bất kỳ trình xác thực tùy chỉnh nào được kế thừa từ IClientValidatable chỉ đơn giản là bỏ qua.Đây là những gì chúng tôi đã làm việc với điều đó đã thất bại trong việc xác nhận bên ngoài của trang web của chúng tôi:

public class AgeValidatorAttribute : ValidationAttribute, IClientValidatable 
{ 
    public int AgeMin { get; set; } 
    public int AgeMax { get; set; } 

    public override bool IsValid(object value) 
    { 
     //run validation 
    } 
} 

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = ErrorMessageString, 
      ValidationType = "agevalidator" 
     }; 

     rule.ValidationParameters["agemin"] = AgeMin; 
     rule.ValidationParameters["agemax"] = AgeMax; 

     yield return rule; 
    } 

Loại bỏ System.Web.Mvc đòi hỏi chúng tôi cũng để loại bỏ GetClientValidationRules và tài liệu tham khảo IClientValidatable. Để làm được điều này và vẫn có xác nhận phía khách hàng, chúng tôi phải tạo ra một lớp mới:

public class AgeValidatorClientValidator : DataAnnotationsModelValidator<AgeValidatorAttribute> 
{ 
    private readonly string _errorMessage; 
    private readonly string _validationType; 

    public AgeValidatorClientValidator(ModelMetadata metadata, ControllerContext context, AgeValidatorAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
     this._errorMessage = attribute.FormatErrorMessage(metadata.DisplayName); 
     this._validationType = "agevalidator"; 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     var rule = new ModelClientValidationRule 
     { 
      ErrorMessage = this._errorMessage, 
      ValidationType = this._validationType 
     }; 

     rule.ValidationParameters["agemin"] = base.Attribute.AgeMin; 
     rule.ValidationParameters["agemax"] = base.Attribute.AgeMax; 

     yield return rule; 
    } 
} 

Như bạn thấy, nó chủ yếu được điều tương tự như trước kia nữa, nó chỉ thực hiện bằng cách sử dụng DataAnnatotationsModelValidator thay hơn IClientValidatable. Có thêm một bước chúng ta cần phải làm gì để thực sự gắn DataAnnotationsModelValidator đến atttribute, và đã xong trong phương pháp Global.asax.cs Application_Start

DataAnnotationsModelValidatorProvider.RegisterAdapter( typeof(AgeValidatorAttribute), typeof(AgeValidatorClientValidator));

Bây giờ bạn có thể sử dụng này cũng giống như bạn sẽ sử dụng một bình thường thuộc tính:

[AgeValidator(AgeMax = 110, AgeMin = 18, ErrorMessage = "The member must be between 18 and 110 years old")] 
public string DateOfBirth { get; set; } 

Tôi biết câu hỏi này là một năm cũ, nhưng tôi đã dành cả ngày hôm qua và một nửa ngày hôm nay để tìm ra vấn đề này. Vì vậy, tôi hy vọng điều này sẽ giúp ai đó chạy vào cùng một vấn đề nếu OP chưa tìm ra câu trả lời.

Xin lưu ý, tôi không bao gồm bất kỳ javascript nào trong quá trình viết này vì nó không yêu cầu thay đổi từ việc triển khai quy tắc xác thực tùy chỉnh chuẩn bằng cách sử dụng jQuery.validate.

+1

Hãy cho tôi một thời gian để tìm ra rằng lớp Validator cần phải đi vào một thư viện mà vẫn có một tham chiếu đến System.Web.Mvc, đó là nó không thể ngồi trong cùng một dự án như lớp thuộc tính. Nhưng một khi tôi đã tìm ra nó hoạt động một điều trị. Rất hữu ích. – bgx