2012-02-19 10 views
5

Acabo de crear una aplicación MVC3 de muestra para aprender la validación. Está utilizando DataAnnotations. He creado un ValidationAttribute personalizado llamado CustomStartLetterMatch. Está implementando "System.Web.Mvc.IClientValidatable". Tengo el código correspondiente del lado del cliente escrito con jQuery discreto. Esto está funcionando como se esperaba.ASP.NET MVC3: ValidationType ModelClientValidationRule

Acerca del validador personalizado: compara la entrada del primer nombre y la entrada del apellido. Lanza un error si el primer carácter de ambos no es el mismo.

Como dije, la aplicación funciona bien. Pero cuando miré el rule.ValidationType = "greaterdate"; me confundí. Quería cambiarlo a algo más como "anotherDefaultType". Cuando lo cambio, falla con el error jQuery.

  1. ¿Cuál es la razón de esto?
  2. ¿Cuáles son los tipos de validación disponibles?
  3. ¿Cuál es el enfoque sugerido para cambiar ValidationType en este scenari

CÓDIGO:

using System; 
using System.ComponentModel.DataAnnotations; 
using System.Collections.Generic; 
namespace MyValidationTEST 
{ 
    public class Person 
    { 
    [Required(ErrorMessage = "First name required")] 
    public string FirstName { get; set; } 

    [CustomStartLetterMatch("FirstName")] 
    [StringLength(5,ErrorMessage = "Must be under 5 characters")] 
    public string LastName { get; set; } 

    [Range(18,50,ErrorMessage="Must be between 18 and 50")] 
    public int Age { get; set; } 

} 



public sealed class CustomStartLetterMatch : ValidationAttribute, System.Web.Mvc.IClientValidatable 
{ 

    private const string _defaultErrorMessage = " First letter of '{0}' must be same as first letetr of '{1}'"; 
    private string _basePropertyName; 

    public CustomStartLetterMatch(string basePropertyName) 
     : base(_defaultErrorMessage) 
    { 
     _basePropertyName = basePropertyName; 
    } 


    //Override FormatErrorMessage Method 
    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(_defaultErrorMessage, name, _basePropertyName); 
    } 


    //Override IsValid 
    protected override ValidationResult IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) 
    { 
     //Get PropertyInfo Object 
     var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName); 
     var baseValue = (string)basePropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     var currentValue = (string)value; 


     string firstLetterBaseValue = baseValue.Substring(0, 1); 
     string firstLetterCurrentValue = currentValue.Substring(0, 1); 

     //Comparision 
     if (!string.Equals(firstLetterBaseValue, firstLetterCurrentValue)) 
     { 
      var message = FormatErrorMessage(validationContext.DisplayName); 
      return new ValidationResult(message); 
     } 

     //Default return - This means there were no validation error 
     return null; 
    } 


    public IEnumerable<System.Web.Mvc.ModelClientValidationRule> GetClientValidationRules(System.Web.Mvc.ModelMetadata metadata, System.Web.Mvc.ControllerContext context) 
    { 
     var rule = new System.Web.Mvc.ModelClientValidationRule(); 
     rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()); 
     rule.ValidationParameters.Add("other", _basePropertyName); 
     rule.ValidationType = "greaterdate"; 
     yield return rule; 
    } 



} 

}

VISTA

@model MyValidationTEST.Person 

@{ 
ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> </script> 

@*UnObtrusive*@ 
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 



<script type="text/javascript"> 

/*Register adapter - addSingleVal*/ 
jQuery.validator.unobtrusive.adapters.addSingleVal("greaterdate", "other"); 


/*Validation type names in unobtrusive client validation rules must consist of only lowercase letters*/ 

/*Add Method*/ 
jQuery.validator.addMethod("greaterdate", 
            function (val, element, other) 
            { 

             var modelPrefix = element.name.substr(0, element.name.lastIndexOf(".") + 1) 
             var otherVal = $("[name=" + modelPrefix + other + "]").val(); 

             if (val && otherVal) 
             { 
              var lastNameFirstLetter = val.substr(0, 1); 
              var firstNameFirstLetter = otherVal.substr(0, 1); 

              if (lastNameFirstLetter != firstNameFirstLetter) 
              { 
               return false; 
              } 
             } 
             return true; 
            }); 


</script> 


@using (Html.BeginForm()) { 
@Html.ValidationSummary(true) 
<fieldset> 
    <legend>Person</legend> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.FirstName) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.FirstName) 
     @Html.ValidationMessageFor(model => model.FirstName) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.LastName) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.LastName) 
     @Html.ValidationMessageFor(model => model.LastName) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.Age) 
    </div> 
    <div class="editor-field"> 
     @Html.EditorFor(model => model.Age) 
     @Html.ValidationMessageFor(model => model.Age) 
    </div> 

    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

<div> 
@Html.ActionLink("Back to List", "Index") 
</div> 

CONTROLADOR:

using System.Web.Mvc; 
namespace MyValidationTEST.Controllers 
{ 
public class RelativesController : Controller 
{ 

    // GET: /Relatives/ 
    public ActionResult Index() 
    { 
     return View(); 
    } 



    // GET: /Relatives/Create 
    public ActionResult Create() 
    { 
     Person person = new Person(); 
     return View(person); 
    } 


    // POST: /Relatives/Create 
    [HttpPost] 
    public ActionResult Create(Person relativeToAdd) 
    { 
     if (ModelState.IsValid) 
     { 
      return RedirectToAction("Index"); 
     } 
     return View(relativeToAdd); 
    } 

    } 

} 

LECTURA:

ASP.NET MVC3 - Custom validation attribute -> Client-side broken

+0

¿Acabó de cambiar 'rule.ValidationType =" greaterdate ";' o cambió el código javascript para que coincida? –

+0

Lo cambié en tres lugares. 1) rule.ValidationType = "greaterdate" 2) Registrando el adaptador en Javascript. 3) En el addomethod en javascript – Lijo

+0

he agregado el código del controlador también para que pueda probarlo usted mismo para ver el error. – Lijo

Respuesta

8

quería cambiar a otra cosa, como "anotherDefaultType"

Puede usar sólo letras minúsculas para la propiedad ValidationType:

rule.ValidationType = "anotherdefaulttype"; 

y luego adapte su script de cliente para reflejar esta modificación:

jQuery.validator.unobtrusive.adapters.addSingleVal("anotherdefaulttype", "other"); 
jQuery.validator.addMethod("anotherdefaulttype", function (val, element, other) { 
    ... 
}); 
+1

prefecto gracias :) – Rajpurohit