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.
- ¿Cuál es la razón de esto?
- ¿Cuáles son los tipos de validación disponibles?
- ¿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
¿Acabó de cambiar 'rule.ValidationType =" greaterdate ";' o cambió el código javascript para que coincida? –
Lo cambié en tres lugares. 1) rule.ValidationType = "greaterdate" 2) Registrando el adaptador en Javascript. 3) En el addomethod en javascript – Lijo
he agregado el código del controlador también para que pueda probarlo usted mismo para ver el error. – Lijo