Рендеринг имени Поля в EditorTemplate (рендеринг через EditorFor())


В настоящее время я создаю бэк-энд администратора для веб-сайта в ASP.NET MVC.

В an ASP.NET приложение MVC, я начал использовать вспомогательный метод 'EditorFor' следующим образом:

<div id="content-edit" class="data-form">
    <p>
        <%= Html.LabelFor(c => c.Title) %>
        <%= Html.TextBoxFor(c => c.Title)%>
    </p>
    <p>
        <%= Html.LabelFor(c => c.Biography) %>
        <%= Html.EditorFor(c => c. Biography)%>
    </p>
</div>

В модели поле "биография"было украшено: [UIHelper ("Html")].

У меня есть частичное представление "Html" (в разделе Views/Shared/EditorTemplates):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>

<textarea class="html">
    <%= Model.ToString() %>
</textarea>

Теперь я хотел бы, чтобы атрибут 'ID' 'textarea' был установлен на имя поля, например:

<textarea id="Biography" class="html">
    ...
</textarea>

Но Я не вижу способа сделать это с текущей установкой.

Все, о чем я могу думать, - это создание 'Html' ViewModel, который содержит свойство 'Value' и свойство 'ControlID'.

Но если бы я основывал взгляд на этом, а не на "системе".XML.Линк.XElement', он больше не будет совместим с вспомогательным методом "EditorFor", и мне придется делать все вручную.

У кого-нибудь уже была подобная проблема?

3 23

3 ответа:

Вы должны иметь возможность извлечь нужный идентификатор из ViewData.TemplateInfo.Свойство представления HtmlFieldPrefix. Вот так:

<%@ Control Language="C#"
      Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>
<textarea id="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" class="html">
    <%= Model.ToString() %>
</textarea>
Чтобы показать, почему это работает, вот место в TemplateHelpers.cs (из источника Mvc2 Preview 1), где ViewData инициализируется для элемента управления шаблоном редактора:
ViewDataDictionary viewData = new ViewDataDictionary(html.ViewDataContainer.ViewData) {
    Model = modelValue,
    TemplateInfo = new TemplateInfo {
        FormattedModelValue = formattedModelValue,
        ModelType = modelType,
        HtmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(expression),
        IsNullableValueType = (underlyingNullableType != null),
    }
};

В приведенном выше вызове инициализируется "выражение" (далее по стеку вызовов) с именем редактируемого свойства.

Кстати, @Sperling ниже поймал деталь I первоначально пропущено: если вы используете (или могли бы использовать) нестандартный HtmlHelper.IdAttributeDotReplacement, то вы захотите заменить точки в свойстве HtmlPrefix на HtmlHelper.IdAttributeDotReplacement.

Использовали это для генерации id (с префиксом модели). Пропустите .Заменить () часть, если вам нужен атрибут name.

<%=Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(String.Empty).Replace(".", HtmlHelper.IdAttributeDotReplacement) %>

В нашем случае мы должны были использовать Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName с ExpressionHelper.GetExpressionText

Который в razor использовался так:

           // hiddenFor was caching the value of this html input, and the value alone, nothing else on the page!
            Expression<Func<Web.ViewModels.ApiSettingsViewModel, int>> expression = (m => m.OrgApiLoginCredentials[i].OrgApiLoginId); 
        }
        <input type="hidden" value="@Model.OrgApiLoginCredentials[i].OrgApiLoginId" name="@Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression))" class="data-org-api-login-id"/>