LabelFor и TextBoxFor не генерируют одинаковые идентификаторы

При использовании следующего кода идентификаторы поля и идентификатор в атрибуте for метки не идентичны.

<%: Html.LabelFor(x => x.Localizations["en"]) %>   => Localizations[en]
<%: Html.TextBoxFor(x=> x.Localizations["en"]) %>  => Localizations_en_

<%: Html.LabelFor(x => x.Localizations["en"].Property) %>
       => Localizations[en]_Property
<%: Html.TextBoxFor(x=> x.Localizations["en"].Property) %>
       => Localizations_en__Property

Я проследил код в отражателе и увидел, что значения совпадают. генерируются разные. Не используется тот же вспомогательный метод.

LabelFor использует HtmlHelper.GenerateIdFromName , а TextBoxFor использует TagBuilder # GenerateId .

Кто-нибудь знает причину этого или обходной путь (кроме написать свой собственный набор ввода / textarea / выберите помощников)? Или это ошибка?

ОБНОВЛЕНИЕ:

Так как я в любом случае использую помощник html для метки со вторым параметром для текста метки, я изменил его, чтобы использовать тот же код генерации идентификатора, что и для помощников поля формы.

public static MvcHtmlString LabelFor(this HtmlHelper helper, Expression> expression, string labelText)
{
    // The main part of this code is taken from the internal code for Html.LabelFor(...).
    var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    var fieldName = ExpressionHelper.GetExpressionText(expression);

    TagBuilder builder = new TagBuilder("label");
    // Generate the id as for the form fields (adds it to self).
    builder.GenerateId(fieldName);
    // Use the generated id for the 'for' attribute.
    builder.Attributes.Add("for", builder.Attributes["id"]);
    // Remove the id again.
    builder.Attributes.Remove("id");
    builder.SetInnerText(labelText);
    return MvcHtmlString.Create(builder.ToString());
}

Это решает мою непосредственную проблему, но не t ответить на вопрос, почему реализация выглядит так, как в MVC2. Если есть причина для этого.

Между прочим: нет необходимости фактически изменять атрибут id / for в HTML5, поскольку совершенно законно иметь идентификатор, похожий на ^ ~ [] , если вы хотел бы. Все основные браузеры поддерживают это. Это хорошо объясняется Матиасом Биненсом .

ОБНОВЛЕНИЕ 2:

На самом деле это вообще не решает проблему, поскольку DefaultModelBinder никак не может с ней связаться. Использование вложенных объектов в словарях, по-видимому, не поддерживается генератором имен полей в MVC 2, поскольку он генерирует:


Вместо того, что хочет связыватель модели:



Странно, что он выходит из коробки таким образом.

Я пытался создать для нее специальное связующее, но я могу MVC2 не может использовать его там, где я пытаюсь его использовать:

ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(IDictionary), new DictionaryModelBinder());
ModelBinders.Binders.Add(typeof(Dictionary), new DictionaryModelBinder());

Итак, сейчас похоже, что он вернулся к ручному созданию значений атрибута name со скрытыми полями .Key .

5
задан Glenn Jorde 18 August 2010 в 12:43
поделиться