Vista
<h2>Index</h2>
@using (Html.BeginForm())
{
<div>Otros @Html.CheckBoxFor(m => m.Otros)</div>
<div>Comentario @Html.TextBoxFor(m => m.Comentario)</div>
<div>@Html.ValidationMessageFor(m => m.Comentario)</div>
<input type="submit" value="Enviar" />
}
Modelopublic class IndexModel
{
public bool Otros { get; set; }
public string Comentario { get; set; }
}
Como siempre, nada raro. Se trata de validar el campo Comentario siempre y cuando el valor de campo Otros sea verdadero. Una vez más busqué algo que de serie me hiciera esta validación pero no encontré nada, así que una vez más me tocó hacer mi propio validador. Para crear un validador simplemente tenemos que heredar de la clase ValidationAttribute y sobreescribir el método IsValid. Pero tendremos que sobreescribir el método IsValid que tiene dos argumentos (object value y ValidationContext validationContext) ya que tenemos que acceder al contexto de validación para obtener el valor de una propiedad. El esqueleto básico del validador sería algo asípublic class RequiredIfTrue : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return base.IsValid(value, validationContext);
}
}
Bien, lo primero que haremos será definir una propiedad (TrueOrFalsePropertyName) en nuestro validador para indicar el nombre de la propiedad enlazada. En nuestro caso, es la propiedad que deberá tener el valor "verdadero" para seguir con la validación, o sea, la propiedad Otros. Luego, en el método IsValid, accederemos a esa propiedad, obtendremos su valor, y comprobaremos si tenemos o no que continuar con la validación. También haremos algunas validaciones como que el nombre de la propiedad es válido y que el tipo que devuelve es un boolean En estos casos, he optado por lanzar una excepción para detener el flujo del programa ya que considero que son fallos de "programación" y que estos fallos no llegarían al usuario final. Con estás premisas nuestro validador queda de la siguiente formapublic class RequiredIfTrue : ValidationAttribute
{
public string TrueOrFalsePropertyName { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (string.IsNullOrEmpty(TrueOrFalsePropertyName))
throw new Exception("No se ha especificado la propiedad 'TrueOrFalsePropertyName'");
// Obtenemos la propiedad
PropertyInfo property = validationContext.ObjectType.GetProperty(TrueOrFalsePropertyName);
if (property == null)
throw new Exception(string.Format("No se encuentra la propiedad '{0}'", TrueOrFalsePropertyName));
// Comprobamos que la propiedad sea de tipo System.Boolean
if (property.PropertyType != typeof(System.Boolean))
throw new Exception(string.Format("La propiedad '{0}' no es de tipo System.Boolean", TrueOrFalsePropertyName));
bool pValue = (bool)property.GetValue(validationContext.ObjectInstance, null);
// Comprobamos el valor
if (pValue && (value == null || (string)value == string.Empty)) return new ValidationResult(ErrorMessage);
return null;
}
}
Y el funcionamiento del validador se puede ver en las siguientes imágenes.
Si no marcamos el campo otros da igual el valor
Si marcamos el campo Otros, el campo Comentario es obligatorio.
Todo correcto otra vez
Happy coding!
Nota: Y para estrenar mi cuenta en SkyDrive, se pueden descargar el código fuente de los siguientes enlaces.
MvcApplication1.rar
MvcApplication1.zip




No hay comentarios:
Publicar un comentario