2012-10-06 18 views
13

Estoy tratando de crear un HtmlHelper que cree campos de formulario compatibles con Bootstrap. Mi primer objetivo era crear un HtmlHelper que va a crear el div que rodea:Obteniendo el nombre de propiedad completo usando ModelMetadata

<div class="control-group"> ... </div> 

Siguiendo el consejo excelente aquí y también aquí me las arreglé para conseguir que funcione con relativa rapidez. Pero no siempre funciona.

Tengo un ViewModel con una propiedad compleja, por lo que en mi forma tengo acceso al campo m=>m.Complex.Element. En mi ayudante, verifico el elemento para ver si hay errores de validación. Yo uso ModelMetadata.FromLambdaExpression(expression, html.ViewData). Los metadatos que obtengo tienen el nombre de propiedad Element, y no Complex.Element.

Cuando consulto el estado del modelo para esta propiedad, no puedo encontrarlo, porque ModelState guarda el nombre completo - Complex.Element.

Puedo buscar coincidencias parciales, con la esperanza de que no haya otro Elemento, pero parece un error desagradable a la espera de suceder. ¿Cómo puedo obtener el nombre completo de la propiedad de la expresión?

Respuesta

27

Es bueno que las fuentes de MVC estén al aire libre. La forma correcta para obtener el nombre de la propiedad ModelState es mediante el uso de

var propertyName = ExpressionHelper.GetExpressionText(expression); 
+1

+1. También tuve el mismo problema. Tu respuesta me ayudó :) –

6

He utilizado lo siguiente para obtenerlo para el modelo actual, sin embargo, puede que tenga que agregar el nombre de la propiedad para obtenerlo para la propiedad.

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix; 

tire hacia afuera lo contrario reflector/ilspy/lo que sea y comprobar cuál es su EditorFor/TextBoxFor o cualquier otro método es la prestación de su editor lo hace.

+0

Me aparece un prefijo vacío. Examinaré las fuentes de MVC 3 y veré cómo Microsoft resuelve esto. Esperaba que alguien más lo supiera y pudiera ahorrarme el tiempo. – zmbq

+0

Utilizo esto (sin "ViewContext.") Dentro de mis HtmlHelper-Extensions y mi Editor/Display-Templates. Funciona bien hasta el momento – Ingo

+1

al escribir su propia extensión html helper puede obtenerlo desde allí 'htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix' – Odys

4

He utilizado una combinación de ambas respuestas para un atributo que necesitaba. Juntas, ambas respuestas proporcionan un atributo de trabajo que puedo usar tanto en vistas como en plantillas de editor anidadas. Aquí está mi ejemplo:

public static MvcHtmlString HasErrorClassFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProperty>> expression) 
{ 
    string expressionText = ExpressionHelper.GetExpressionText(expression); 

    string htmlFieldPrefix = htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix; 

    string fullyQualifiedName; 

    if (htmlFieldPrefix.Length > 0) 
    { 
     fullyQualifiedName = string.Join(".", htmlFieldPrefix, expressionText); 
    } 
    else 
    { 
     fullyQualifiedName = expressionText; 
    } 

    bool isValid = htmlHelper.ViewData.ModelState.IsValidField(fullyQualifiedName); 

    if (!isValid) 
    { 
     return MvcHtmlString.Create("has-error"); 
    } 

    return MvcHtmlString.Empty; 
} 
Cuestiones relacionadas