ASP.NET GetFullHtmlFieldId not returning valid id

梦想与她 提交于 2019-12-11 06:55:28

问题


In MVC2 template, I normally use this.ViewData.TemplateInfo.GetFullHtmlFieldId(fieldName) to generate the id field of an html element. This has worked in most of the cases.

However this method does not actually return valid id field, it merely prefix fieldName with ViewData.TemplateInfo.HtmlFieldPrefix, this is causing problems for me when rendering collections which has [] in the HtmlFieldPrefix.

I have been manually converting those characters to _ where I find the need, but this seems to be not elegant (repeated code), has anyone found a good way to generate id field properly?


回答1:


Can you be more specific about the kind of problems do you have?

For example, there is an elegant approach to editing variable length list with validation support provided. While it doesn't use templates still remains DRY with partial views.

While the ids are inconsistent - the names are OK and only problem I encountered is that using jquery.infieldlabel it appeared that label's for attribute (generated by GetFullHtmlFieldId inside LabelFor helper) didn't match id of the appropriate TextBoxFor input. So I created LabelForCollectionItem helper method that just uses the same method for id generation as the TextBox - TagBuilder.GenerateId(fullName)

Maybe the code doesn't correspond to your need but hope it will help somebody since I found your question among the first searching for solution to my problem.

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


来源:https://stackoverflow.com/questions/2838196/asp-net-getfullhtmlfieldid-not-returning-valid-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!