2011-11-23 5 views
7

Estoy tratando de evitar el hecho de que cuando escribieron asp.net MVC 3 se olvidó de incluir código para agregar los atributos de validación discretos a las listas de selección y su "fix" para esto es incluir en MVC 4, que no es sangriento para cualquiera que use MVC 3.Cómo utilizar Html.GetUnobtrusiveValidationAttributes()

Mi trabajo propuesto es usar Html.GetUnobtrusiveValidationAttributes() para agregarlos yo mismo, como cualquier otro atributo personalizado, pero no puedo encontrar la sintaxis correcta para llamar al método. Hay 2 sobrecargas, una toma una cadena y la otra toma una cadena y una clase ModelMetaData. Entiendo el param de metadatos, supongo que acabo de pasar el ViewData.ModelMetadata, pero ¿cuál debería ser la cadena? La documentación de MSDN dice que es "el atributo de nombre HTML especificado" que no tiene sentido para mí. El atributo de nombre HTML de qué? La lista de selección? ¿Por qué lo necesitaría y cómo lo ayuda a saber qué propiedad de mi modelo quiero que valide? Mirando ejemplos de uso que todos parecen pasar en el nombre de la propiedad en mi modelo para los que quiero los atributos de validación, lo cual tiene sentido. Desafortunadamente no puedo obtener el método para devolver nada más que una colección vacía sin importar lo que pase.

Mi clase de modelo se llama Evento y mi propiedad se llama EventTypeID. Estoy utilizando una clase de viewmodel ligeramente diferente como base para la vista porque necesito mostrar una lista de eventos y también permitir que se ingrese un nuevo evento en la misma vista, así que tengo una clase simple de viewmodel como la siguiente:

public class EventViewModel 
{ 
    public Model.Event NewEvent { get; set; } 
    public IEnumerable<Model.Event> Events { get; set; } 
} 

La lista desplegable se asigna a la propiedad como: @Html.DropDownListFor(model => model.NewEvent.EventTypeID ¿qué paso como la cadena a Html.GetUnobtrusiveValidationAttributes(string) o Html.GetUnobtrusiveValidationAttributes(string, ModelMetadata) para obtener los atributos de esta propiedad. Lo he intentado:

Html.GetUnobtrusiveValidationAttributes("EventTypeID") 
Html.GetUnobtrusiveValidationAttributes("EventTypeID",ViewData.ModelMetadata) 
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID") 
Html.GetUnobtrusiveValidationAttributes("NewEvent.EventTypeID",ModelMetadata) 

Todos devuelven una colección vacía.

Sé que mi modelo es correcto porque si cambio la llamada de Html.DropDownListFor a Html.TextBoxFor, entonces la validación "simplemente funciona" sin que tenga que hacer otra cosa que agregar los atributos de validación a mi clase de modelo.

EDIT:

Sólo intentado convertir la validación del lado del cliente en otro, la validación del lado del servidor funciona muy bien para todas las listas de selección.

Respuesta

0

Aquí hay un enlace a una respuesta que he publicado, mostrando un HtmlHelper escribí para proporcionar la validación discreta para dropdownlists: MVC 3 dropdownlist validation not working for complex view model

ACTUALIZACIÓN

¿Estás tratando de obtener los atributos en un HtmlHelper, o en línea en su punto de vista?

Suponiendo que está tratando de obtener los atributos en su vista, ese es el problema.

Primero, debe comprender que ModelMetadata no representa un solo objeto disponible en todo su modelo. Más bien, representa los metadatos de un elemento en particular, ya sea su modelo o cualquier propiedad dentro del modelo. Un mejor nombre descriptivo sería ObjectMetadata, ya que ModelMetadata es el metadato de un objeto específico, ya sea un modelo, un modelo anidado o una propiedad específica.

ModelMetadata en la vista son solo los metadatos para el modelo de nivel superior. Debe obtener ModelMetadata para la propiedad a la que está vinculada la lista desplegable.Si usas un helper, entonces el helper pasa el ModelMetadata correcto por rutina. Si usted utiliza su punto de vista, es necesario para participar en un poco de gimnasia para obtener el ModelMetadata correcta, véase, por ejemplo, mi respuesta aquí: Validating and editing a “Changeable”/optional type in Asp.net MVC 3

+1

que había visto que ya he publicado antes, no estoy seguro de entender plenamente el código de modo que he abstenido de usarlo. ¿Podría explicarme lo que estoy haciendo mal según mi pregunta y explicar lo que debería pasar a GetUnobtrusiveValidationAttributes() para obtener los atributos para mi modelo? –

13

Para aquellos que todavía buscando una respuesta, esto funciona para mí:

public static IDictionary<string, object> UnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertyExpression) 
{ 
    var propertyName = html.NameFor(propertyExpression).ToString(); 
    var metadata = ModelMetadata.FromLambdaExpression(propertyExpression, html.ViewData); 
    var attributes = html.GetUnobtrusiveValidationAttributes(propertyName, metadata); 
    return attributes; 
} 

tenga en cuenta que estoy usando .Net MVC 4, usted no tiene el método html.NameFor en MVC 3. sin embargo, creo que esto se puede hacer en MVC 3 con el siguiente método:

var propertyName = ExpressionHelper.GetExpressionText(propertyExpression); 
3

usted puede usarlo en línea

Ejemplo de elemento select

<select name="@Html.NameFor(m=> m.MyProperty)" 
     id="@Html.IdFor(m=> m.MyProperty)" 
     @Html.Raw(string.Join(" ", Html.GetUnobtrusiveValidationAttributes(Html.NameFor(m => m.MyProperty).ToString()).Select(x => x.Key.ToString() + "=\"" + x.Value + "\""))) 
>