ASP.NET GetFullHtmlFieldId не возвращает действительный идентификатор

В шаблоне MVC2 я обычно использую this.ViewData.TemplateInfo.GetFullHtmlFieldId(fieldName) для создания поля id элемента html. Это сработало в большинстве случаев.

Однако этот метод на самом деле не возвращает допустимое поле идентификатора, это просто префикс fieldName на ViewData.TemplateInfo.HtmlFieldPrefix, это вызывает у меня проблемы при рендеринге коллекций, у которых [] в HtmlFieldPrefix.

Я вручную преобразовывал эти символы в _ там, где я нахожу это необходимым, но это кажется не изящным (повторяющийся код), нашел ли кто-нибудь хороший способ правильно сгенерировать поле идентификатора?


person Bill Yang    schedule 14.05.2010    source источник


Ответы (1)


Не могли бы вы подробнее рассказать о проблемах, которые у вас есть?

Например, есть элегантный подход к редактирование списка переменной длины с помощью поддержка проверки. Хотя он не использует шаблоны, остается СУХИМ с частичным просмотром.

Хотя идентификаторы несовместимы - имена в порядке, и единственная проблема, с которой я столкнулся, заключается в том, что при использовании jquery.infieldlabel оказалось, что метка для атрибута (сгенерированная GetFullHtmlFieldId внутри помощника LabelFor) не соответствует идентификатору соответствующего ввода TextBoxFor. Поэтому я создал вспомогательный метод LabelForCollectionItem, который просто использует тот же метод для генерации идентификатора, что и TextBox - 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;
    }
}
person Sasha    schedule 19.05.2010
comment
Итак, что произойдет в вашем методе, если htmlFieldName содержит квадратные скобки? например Пользователи [0] - person Bill Yang; 20.05.2010
comment
Html.LabelForCollectionItem (x = ›x.Users [0] .Name) возвращает‹ label для = Users_0__Name ... - person Sasha; 20.05.2010
comment
Это интересный способ сделать это, помог мне найти решение для нашей конкретной ситуации. Спасибо! (Я бы проголосовал за ваш ответ, если вы можете его отредактировать - так что обходите глупые правила stackoverflow) - person Bill Yang; 21.05.2010