2011-03-01 20 views
13

Esto es más una pregunta teórica.¿Cómo funciona realmente DataAnnotations en MVC?

Actualmente estoy examinando la validación de MVC 3 usando ComponentModel.DataAnnotations, y todo funciona automágicamente, especialmente en el lado del cliente.

De alguna manera, algo comprueba esos atributos y genera javascript para la validación (o atributos html5, si se usa el modo discreto), y funciona.

Mi pregunta es, ¿qué genera el javascript del lado del cliente y cómo puedo acceder y modificarlo? Por ejemplo, quiero manejar los atributos de dataannotación dados de forma un poco diferente, o manejar atributos personalizados (he descubierto que puedo derivarlos de ValidationAttribute, pero tal vez por alguna razón no quiero).

¿Alguien me puede explicar lo que realmente sucede? (O los enlaces a buenas explicaciones también serían buenos, ya que solo encontré tutoriales para usar dataannotaciones)

EDITAR: También con derivación de ValidationAttribute, la validación del lado del cliente no funciona automáticamente. ¿Por qué?

Respuesta

15

MVC3 tiene un nuevo mecanismo de jQuery Validación que vinculan jQuery Validación y validación de atributos de metadatos, esta es la imagen jquery.validate.unobtrusive que se lleva todos los data- atributos y trabajar con ellos, al igual que antes cuando se establece el

<add key="UnobtrusiveJavaScriptEnabled" value="false" /> 

Todos que hay que hacer es venir con su propia Validación atributos personalizados, para eso tienes 2 opciones:

  • Crear una de validación personalizada Atributo que hereda la interfaz ValidationAttribute y anular el IsValid

o

  • Crear un Auto Validar Modeloutilizar el modelo IValidatebleObject que todo lo que necesita es devolver el Validate método

en MVC3 ahora hav Hay un método que puede anular que tiene un objeto ValidationContext, donde puede obtener todas las referencias, propiedades y valores de cualquier otro objeto en el formulario

Cree el suyo propio, y ese archivo discreto manejará la asignación de su personalización El validador necesita y funcionará junto con el complemento jQuery Validation.

NO cambias el javascript ... ¡así es el 90 y no el modo MVC!

por ejemplo, si desea validar, digamos 2 fechas que el último no puede ser inferior a la primera (período de tiempo, por ejemplo)

public class TimeCard 
{ 
    public DateTime StartDate { get; set; } 

    [GreaterThanDateAttribute("StartDate")] 
    public DateTime EndDate { get; set; } 
} 

la creación de un personalizada Validación

public class GreaterThanDateAttribute : ValidationAttribute 
{ 
    public string GreaterThanDateAttribute(string otherPropertyName) 
     :base("{0} must be greater than {1}") 
    { 
     OtherPropertyName = otherPropertyName; 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return String.Format(ErrorMessageString, name, OtherPropertyName); 
    } 

    public override ValidateionResult IsValid(object value, ValidationContext validationContext) 
    { 
     var otherPropertyInfo = validationContext.ObjectTYpe.GetProperty(OtherPropertyName); 
     var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var thisDate = (DateTime)value; 

     if(thisDate <= otherDate) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     return null;   
    }  
} 

si se utiliza el modelo de autovalidante continuación, el código sería simplemente

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
{ 
    if(EndDate <= StartDate) 
     yield return new ValidationResult("EndDate must be grater than StartDate"); 
} 

Tenga en cuenta que la validación personalizada es genérica, es por eso que muchos códigos, y el modelo de autovalidación solo funciona en el modelo aplicado.

creo que sirve


añade

No me explico el encargo del cliente Validación parte , no dudes en preguntar si necesita ejemplos, pero básicamente:

Es más fácil en MVC3 (si, por supuesto, usted comprende jQuery.Validate) todo lo que necesita hacer es:

  • Implementar IClientValidateble
  • implementar un método de validación de jQuery
  • Implementar un adaptador discreta

para crear esta 3 cosas, vamos a llevar esto GreaterThanDateAttribute en cuenta y crear el encargo del lado del cliente de validación. Para eso es necesario para codificar el siguiente:

anexados para la GreaterThanDateAttribute

public IEnumerable<ModelCLientValidation> GetCLientValidationRules(ModelMetadata metadata, ControllerContext context) 
{ 
    var rule = new ModelCLientValidationRule(); 
    rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); 
    rule.ValidationType = "greater"; // This is what the jQuery.Validation expects 
    rule.ValidationParameters.Add("other", OtherPropertyName); // This is the 2nd parameter 

    yield return rule; 
} 

Luego hay que escribir la nueva jQuery Validador y el adaptador metadatos que unirá la jQuery.Validation con su código proporcionar las correctas data- atributos para ese campo (si, por supuesto, es cierto UnobtrusiveJavaScriptEnabled)

crear un nuevo archivo js y adjuntar a su <head> para examp Le como

<script src="@Url.Content("~/Scripts/customValidation.js")" type="text/javascript"></script> 

y anexar la nueva validación

jQuery.validator.addMethod("greater", function(value, element, param) { 
    // we need to take value and compare with the value in 2nd parameter that is hold in param 
    return Date.parse(value) > Date.parse($(param).val()); 
}); 

y luego escribimos el adaptador

jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options) { 
    // pass the 'other' property value to the jQuery Validator 
    options.rules["greater"] = "#" + options.param.other; 
    // when this rule fails, show message that comes from ErrorMessage 
    options.messages["greater"] = options.message; 
}); 
+0

Gracias por su respuesta. El modelo de autovalidación fue un nuevo enfoque para mí. Pero malinterpretaste la pregunta.No me interesaba realmente crear los atributos de validación personalizados, pero me interesaba la forma en que los atributos javascript (o html5, si se selecciona el modo discreto) se generan a partir de los atributos de validación. Disculpa que forcé un ejemplo infantil de cómo este conocimiento sería útil, pero ese no era realmente el objetivo de mi publicación. Dejando esto de lado, tu respuesta fue realmente buena. – SoonDead

+1

Lo siento, pero no estoy siguiendo. ¿Quieres saber cómo se genera 'data-'? ese es el trabajo del método helper 'Html.TextBoxFor()', ya que ya conoce todas las Anotaciones de datos que necesita el campo, y si la configuración Abstenerse es verdadera, generará todos los 'datos-' que necesita, luego los enlaces del Adaptador eso en jQuery.Validate plugin. Me sentí libre de pedir ejemplos, puedo hacer todo esto genial para el ejemplo anterior de 'GreaterThanDateAttribute', quizás te ayude a entenderlo mejor. – balexandre

+0

ejemplo de validación de cliente personalizado, créelo y juegue con él para que pueda ver lo que hace la 'validación de cliente personalizado '. Se agregará a '' los atributos 'data-val' y' data-val-greater' y todos los atributos necesarios para realizar la validación del lado del cliente. ** ** ¿Este último ejemplo responde su pregunta? – balexandre

Cuestiones relacionadas