2013-01-11 5 views
5

Jak utworzyć niestandardowy atrybut sprawdzania poprawności po sprawdzeniu poprawności po stronie klienta bez implementacji IClientValidatable?ASP.NET MVC: Implementacja sprawdzania poprawności strony klienta z atrybutem bez IClientValidatable

W jaki sposób sprawdza się po stronie klienta po ?

Powodem tego jest to, że używam obiektów z klas w innym projekcie jako modeli w moich widokach i nie chcę dodawać odwołania do tego projektu z System.Web.MVC.

EDIT, aby dodać więcej informacji:

  • wiem, że IClientValidatable służy do dodawania niestandardowych atrybutów do HTML do późniejszego wykorzystania przez dyskretny walidacji.

  • Wiem, że będę musiał dodać kod javascript, aby dokonać sprawdzenia poprawności w klienta.

Nie wiem, jak użyć informacji z niestandardowego atrybutu sprawdzania poprawności, aby dodać niezbędne atrybuty do kodu HTML, aby dyskretne sprawdzanie poprawności działało.

To mój atrybut niestandardowy walidacji:

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

     if (guidValue == null) 
      return false; 

     return guidValue != Guid.Empty; 
    } 
} 

To moja własność z atrybutem stosowane:

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

I wreszcie mam renderowania ukryte wejście dla tej właściwości w widoku za pomocą Html.HiddenFor.

Jak mogę uzyskać komunikat o błędzie z atrybutu, aby zastosować go do kodu HTML? Czy powinienem zrobić to sam, używając Reflection, czy jest lepszy sposób?

A następnie, jak mogę powiedzieć, aby Html.HiddenFor użyć tych informacji, aby dodać niezbędne atrybuty do kodu HTML?

Odpowiedz

0

Nie można przeprowadzić niestandardowego sprawdzania poprawności na kliencie, chyba że wdrożono metodę IClientValidatable. Do tego trzeba również dodać skrypt klienta.

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

+0

Przykro mi, ale musi to być sposób, ponieważ atrybuty z DataAnnotations są rozpoznawane przez pomocników html i wyprowadzają html z atrybutami wymaganymi do sprawdzania poprawności klienta. Wiem, że będę musiał dodać skrypt klienta i to nie jest problem. – Marques

5

Mieliśmy podobny problem. Mamy model, którego używamy do tworzenia naszych kont, który używa IClientValidatable na swoich niestandardowych atrybutach. Stworzyliśmy jednak proces tworzenia konta wsadowego, który znajduje się poza witryną, do której nie mogliśmy odwoływać się do System.Web.Mvc. Z tego powodu, gdy nazywaliśmy Validator.TryValidateObject, każdy niestandardowy weryfikator, który odziedziczył po IClientValidatable, był po prostu pomijane.Oto co nam praca z braku który został do sprawdzania poprawności poza naszej stronie internetowej:

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

Usuwanie System.Web.Mvc wymaga od nas również usunąć GetClientValidationRules i IClientValidatable odniesienia. W tym celu i jeszcze walidacji po stronie klienta, musieliśmy stworzyć nową klasę:

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

Jak widać, to jednak w zasadzie to samo, co było kiedyś, to właśnie odbywa się za pomocą DataAnnatotationsModelValidator raczej niż IClientValidatable. Istnieje jeszcze jeden krok musimy zrobić, aby rzeczywiście dołączyć DataAnnotationsModelValidator do atttribute, a to odbywa się w sposób Global.asax.cs Application_Start

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

Teraz można to wykorzystać, tak jak byłoby użyć normalny atrybut:

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

Wiem, że to pytanie ma rok, ale spędziłem cały dzień wczoraj i pół dnia, próbując rozwiązać ten problem. Mam więc nadzieję, że pomoże to komuś, kto napotka na ten sam problem, jeśli OP jeszcze nie wymyślił odpowiedzi.

Proszę zauważyć, że nie uwzględniłem żadnego javascript w tym zapisie, ponieważ nie wymagało to żadnych zmian ze standardowej implementacji niestandardowych reguł sprawdzania poprawności za pomocą jQuery.validate.

+1

Zajęło mi trochę czasu, aby dowiedzieć się, że klasa Validator musi przejść do biblioteki, która wciąż ma odniesienie do System.Web.Mvc, to znaczy, że nie może siedzieć w tym samym projekcie, co klasa Attribute. Ale kiedy już to wymyśliłem, działa to naiwnie. Bardzo pomocne. – bgx

Powiązane problemy