2010-05-14 86 views
1

在MVC2模板中,我通常使用this.ViewData.TemplateInfo.GetFullHtmlFieldId(fieldName) 來生成html元素的id字段。這在大多數情況下都有效。ASP.NET GetFullHtmlFieldId不返回有效標識

但是這種方法實際上並不返回valid id field,它只是前綴fieldNameViewData.TemplateInfo.HtmlFieldPrefix,這使這在HtmlFieldPrefix有[]集合時造成的問題對我來說。

我一直在手動將這些字符轉換爲_,在那裏我發現需要,但這似乎不是優雅(重複代碼),有沒有人找到正確生成id字段的好方法?

回答

3

你對這類問題有更具體的瞭解嗎?

例如,有一個editing variable length list的優雅方法,validation support提供。儘管它不使用模板,但仍然保留DRY與部分視圖。

雖然id不一致,但名稱還是可以的,只有我遇到的問題是,使用jquery.infieldlabel時,標籤的for屬性(由LabelForHelper中的GetFullHtmlFieldId生成)與適當的TextBoxFor輸入的id不匹配。所以我創建只是用同樣的方法進行ID生成的文本框LabelForCollectionItem助手方法 - TagBuilder.GenerateId(fullName)

也許代碼不符合您的需要,但希望這將幫助別人,因爲我發現第一個搜索中你的問題解決我的問題。

public static class LabelExtensions 
{ 
    /// <summary> 
    /// Generates Label with "for" attribute corresponding to the id rendered by input (e.g. TextBoxFor), 
    /// for the case when input is a collection item (full name contains []). 
    /// GetFullHtmlFieldId works incorrect inside Html.BeginCollectionItem due to brackets presense. 
    /// This method copies TextBox's id generation. 
    /// </summary> 
    public static MvcHtmlString LabelForCollectionItem<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, 
       string labelText = null, object htmlAttributes = null) where TModel : class 
    { 
     var tag = new TagBuilder("label"); 
     tag.MergeAttributes(new RouteValueDictionary(htmlAttributes)); // to convert an object into an IDictionary 

     // set inner text 
     string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 
     string innerText = labelText ?? GetDefaultLabelText(html, expression, htmlFieldName); 
     if (string.IsNullOrEmpty(innerText)) 
     { 
      return MvcHtmlString.Empty; 
     } 
     tag.SetInnerText(innerText); 

     // set for attribute 
     string forId = GenerateTextBoxId(tag, html, htmlFieldName); 
     tag.Attributes.Add("for", forId); 

     return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal)); 
    } 

    /// <summary> 
    /// Extracted from System.Web.Mvc.Html.InputExtensions 
    /// </summary> 
    private static string GenerateTextBoxId<TModel>(TagBuilder tagBuilder, HtmlHelper<TModel> html, string htmlFieldName) 
    { 
     string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName); 
     tagBuilder.GenerateId(fullName); 
     string forId = tagBuilder.Attributes["id"]; 
     tagBuilder.Attributes.Remove("id"); 
     return forId; 
    } 

    /// <summary> 
    /// Extracted from System.Web.Mvc.Html.LabelExtensions 
    /// </summary> 
    private static string GetDefaultLabelText<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, string htmlFieldName) 
    { 
     var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); 
     return labelText; 
    } 
} 
+0

所以在你的方法中,如果htmlFieldName包含方括號會發生什麼?例如「Users [0]」 – 2010-05-19 21:37:28

+0

Html.LabelForCollectionItem(x => x.Users [0] .Name)返回

+0

這是一個有趣的方式,幫助我上來爲我們的具體情況提供解決方案。謝謝! (我會投票你的答案,如果你可以編輯它 - 所以繞過愚蠢的計算器規則) – 2010-05-20 20:08:46

相關問題