2012-10-06 16 views
13

我试图创建一个HtmlHelper来创建Bootstrap兼容的表单域。我的第一个目标是创建一个的HtmlHelper,将创建周围的div:这里使用ModelMetadata获取完整的属性名称

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

继出色的意见,并在这里,我设法得到它相对迅速开展工作。但它并不总是有效。

我有一个复杂的属性ViewModel,所以在我的形式我访问字段m=>m.Complex.Element。在我的帮手中,我检查元素是否存在验证错误。我使用ModelMetadata.FromLambdaExpression(expression, html.ViewData)。我收到的元数据有属性名称Element,而不是Complex.Element

当我检查此属性的ModelState时,我无法找到它,因为ModelState保留全名 - Complex.Element

我可以寻找部分匹配,希望没有其他元素,但这似乎是一个等待发生的讨厌的错误。我如何从表达式中获得完整的属性名称?

回答

27

这是一件好事,MVC资源公开。正确的方法来获得的ModelState属性名称是通过使用

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

+1。我也有同样的问题。你的回答帮了我:) –

6

我已经使用以下来获取它当前的模型之前,您可能需要附加属性名称,以获得它的属性。

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix; 

否则拉出反射器/ ilspy /不管,并检查你的EditorFor/TextBoxFor或任何方法使你的编辑器。

+0

我得到一个空的前缀。我会研究MVC 3的来源,看看微软如何解决这个问题。我希望别人知道它,并可以节省我的时间。 – zmbq

+0

我在我的HtmlHelper-Extensions和我的编辑器/显示模板中使用了这个(没有“ViewContext。”)。到目前为止工作良好 – Ingo

+1

当你编写自己的html助手扩展,你可以从那里'htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix' – Odys

4

我用两个答案,因为我需要一个属性的组合。这两个答案一起提供了一个我可以在视图和嵌套编辑器模板中使用的工作属性。这里是我的例子:

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; 
}