2013-01-11 7 views
5

Wie kann ich ein benutzerdefiniertes Validierungsattribut mit clientseitiger Validierung erstellen, ohne IClientValidatable zu implementieren?ASP.NET MVC: Implementieren der clientseitigen Validierung mit Attribut ohne IClientValidatable

Wie wird die System.ComponentModel.DataAnnotations.RequiredAttribute Client-Seite validiert?

Der Grund dafür ist, weil ich Objekte aus Klassen in einem anderen Projekt als Modelle in meinen Ansichten verwenden, und ich möchte nicht die System.Web.MVC Referenz zu diesem Projekt hinzufügen.

EDIT weitere Informationen hinzuzufügen:

  • Ich weiß, dass IClientValidatable Brauch hinzuzufügen verwendet wird Attribute der HTML durch die unaufdringliche Validierung später verwendet werden.

  • Ich weiß, ich muss den Javascript-Code hinzufügen, um die Validierung in der Client zu machen.

Was ich nicht weiß, ist, wie die Informationen aus dem Attribut benutzerdefinierten Validierung zu verwenden, um die erforderlichen Attribute der HTML hinzufügen für eine unauffällige Validierung zu arbeiten.

Dies ist meine benutzerdefinierte Validierung Attribut:

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

     if (guidValue == null) 
      return false; 

     return guidValue != Guid.Empty; 
    } 
} 

Das ist mein Grundstück mit dem Attribut angewendet:

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

Und schließlich einen versteckten Eingang für diese Eigenschaft in der Ansicht Ich bin Rendering mit Html.HiddenFor.

Nun, wie bekomme ich die Fehlermeldung aus dem Attribut, um es auf die HTML anwenden? Sollte ich es selbst mit Reflection machen oder gibt es einen besseren Weg?

Und dann, wie kann ich Html.HiddenFor sagen, diese Informationen zu verwenden, um dem HTML die notwendigen Attribute hinzuzufügen?

Antwort

0

Sie können keine benutzerdefinierte Überprüfung auf dem Client durchführen, wenn Sie IClientValidatable nicht implementieren. Und dazu müssen Sie auch ein Client-Skript hinzufügen.

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

+0

Es tut mir leid, aber es muss ein Weg sein, weil die Attribute von DataAnnotations von den HTML-Helfern erkannt werden und sie html mit den für die Client-Validierung erforderlichen Attributen ausgeben. Ich weiß, dass ich Client-Skript hinzufügen muss, und das ist kein Problem. – Marques

5

Wir hatten ein ähnliches Problem. Wir haben ein Modell, das wir für unsere Kontoerstellung verwenden, das IClientValidatable für seine benutzerdefinierten Attribute verwendet. Wir haben jedoch einen Batch-Kontoerstellungsprozess erstellt, der sich außerhalb der Website befindet, auf den wir System.Web.Mvc nicht verweisen konnten. Aus diesem Grund war jeder benutzerdefinierte Validator, der von IClientValidatable geerbt wurde, einfach "Validator.TryValidateObject" übersprungen.Hier ist, was wir arbeiten mit, dass versagt außerhalb unserer Website zu überprüfen:

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

Entfernen von System.Web.Mvc uns verpflichtet, auch GetClientValidationRules und die IClientValidatable Referenz zu entfernen. Um dies zu tun und noch Clientseite Validierung haben, mussten wir eine neue Klasse erstellen:

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

Wie man sehen kann, tut es im Wesentlichen dasselbe wie früher, es ist nur die DataAnnatotationsModelValidator durchgeführt unter Verwendung eher als IClientValidatable. in der Global.asax.cs Application_Start Methode Es gibt einen weiteren Schritt, den wir tun müssen, um tatsächlich die DataAnnotationsModelValidator zum atttribute zu befestigen, und dass

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

Jetzt können Sie diese als verwenden nur würden Sie für ein normalen Gebrauch gemacht werden Attribut:

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

ich weiß, diese Frage ein Jahr alt ist, aber ich habe gestern den ganzen Tag und die Hälfte der heute versucht, dieses Problem herauszufinden. Ich hoffe also, dass dies jemandem hilft, der auf das gleiche Problem stößt, wenn OP die Antwort noch nicht herausgefunden hat.

Bitte beachten Sie, dass ich in dieses Write-up kein Javascript aufgenommen habe, da es keine Änderungen an der Standardimplementierung von benutzerdefinierten Validierungsregeln mit jQuery.validate erforderlich machte.

+1

Ich brauchte eine Weile, um herauszufinden, dass die Validator-Klasse in eine Bibliothek gehen muss, die immer noch einen Verweis auf System.Web.Mvc hat, dh sie kann nicht im selben Projekt wie die Attributklasse sitzen. Aber sobald ich es herausgefunden habe, funktioniert es ein Vergnügen. Sehr hilfreich. – bgx

Verwandte Themen