2011-10-06 7 views
6

He creado mi propia costumbre ValidationAttribute:personalizada ValidationAttribute no disparar llamada a la función IsValid en vista del modelo

public class UrlValidationAttribute : ValidationAttribute 
{ 
    public UrlValidationAttribute() {} 

    public override bool IsValid(object value) 
    { 
     if (value == null) 
      return true; 

     var text = value as string; 
     Uri uri; 

     return (!string.IsNullOrWhiteSpace(text) && 
       Uri.TryCreate(text, UriKind.Absolute, out uri)); 
    } 
} 

estoy usando que en una de mis modelos y funciona perfectamente. Sin embargo, ahora que estoy tratando de usarlo en un modelo de vista:

public class DeviceAttribute 
{ 
    public DeviceAttribute(int id, attributeDefinition, String url) 
    { 
     ID = id; 
     Url = url; 
    } 

    public int ID { get; set; } 

    [UrlValidation] 
    public String Url { get; set; } 
} 

El modelo de vista se utiliza en la vista parcial de esta manera:

@model List<ICMDB.Models.DeviceAttribute> 

<table class="editor-table"> 

@foreach (var attribute in Model) 
{ 
    <tr> 

     @Html.HiddenFor(a => attribute.ID) 

     <td class="editor-label"> 
      @Html.LabelFor(a => attribute.Url) 
     </td> 

     <td class="editor-field"> 
      @Html.TextBoxFor(a => attribute.Url)    
      @Html.ValidationMessageFor(a => attribute.Url) 
     </td> 

    </tr> 
} 

</table> 

Por alguna razón desconocida, mientras que el constructor de UrlValidationAttribute incendios, la función IsValid no se activa. ¿Algunas ideas?

Editar: En una investigación más profunda, parece que esto está sucediendo porque el modelo de vista DeviceAttribute es en realidad el modelo de vista para un parcial. La página completa se pasa a un modelo de vista diferente que contiene la lista de modelos de vista DeviceAttribute. Entonces, cuando se llama a mi acción de controlador, se construye el modelo de vista de página completa y se llenan sus valores, pero no se construyen modelos de vista DeviceAttribute, por lo que no se ejecuta ninguna validación.

+0

Quizás intente invalidar @protected override ValidationResult IsValid (valor del objeto, ValidationContext validationContext) @: este es el método que debe sobrescribirse para ValidationAttribute. NB: asegúrese de llamar al controlador de ValidationResult con la información del miembro que se encuentra en el contexto de validación. –

+0

Intenté eso también, no funcionó. Creo que tiene algo que ver con el hecho de que esto está en una vista parcial, por lo que 'List ' no se devuelve al controlador para su validación ... – link664

Respuesta

-1

Yo recomendaría que use plantillas de editor en lugar de escribir bucles foreach. Supongo que su principal modelo de vista es como la siguiente:

public class MyViewModel 
{ 
    public List<DeviceAttribute> Devices { get; set; } 
    ... 
} 

En su vista principal:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    <table class="editor-table"> 
     @Html.EditorFor(x => x.Devices) 
    </table> 
    <input type="submit" value="OK" /> 
} 

y en la plantilla correspondiente editor (~/Views/Shared/EditorTemplates/DeviceAttribute.cshtml):

@model DeviceAttribute 
<tr> 
    @Html.HiddenFor(x => x.ID) 

    <td class="editor-label"> 
     @Html.LabelFor(x => x.Url) 
    </td> 

    <td class="editor-field"> 
     @Html.TextBoxFor(x => x.Url)    
     @Html.ValidationMessageFor(x => x.Url) 
    </td> 
</tr> 

Y su acción POST recupera el modelo de vista:

[HttpPost] 
public ActionResult Index(MyViewModel model) 
{ 
    ... 
} 

Ahora el enlace de modelo predeterminado vinculará con éxito todos los valores en el modelo de vista y la validación de patada.

Aquí hay un nice blog post sobre plantillas.

+0

Encontré que esto no funcionaba. – Bardicer

Cuestiones relacionadas