Renderizando o nome de campo em um editorTemplate (renderizado através do editorfor ())
-
18-09-2019 - |
Pergunta
Atualmente, estou construindo o back-end do Admin para um site no ASP.NET MVC.
Em um aplicativo ASP.NET MVC, comecei a usar o método 'editorfor' como assim:
<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>
No modelo, o campo de 'biografia' foi decorado com: [uihelper ("html")].
Eu tenho uma visão parcial 'html' (em Views/Shared/EditorTemplates):
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>
<textarea class="html">
<%= Model.ToString() %>
</textarea>
Agora eu gostaria de ter o atributo 'id' do 'textarea' definido com o nome do campo, assim:
<textarea id="Biography" class="html">
...
</textarea>
Mas não consigo ver uma maneira de fazer isso com a configuração atual.
Tudo o que consigo pensar é criar uma viewModel 'HTML' que contém uma propriedade 'Value' e uma propriedade 'ControlId'.
Mas se eu baseei a visualização de que, em vez de 'System.xml.linq.xelement', ela não seria mais compatível com o método 'editor para auxiliar' e eu teria que fazer tudo manualmente.
Alguém já teve um problema semelhante?
Solução
Você poderá retirar o ID desejado da propriedade ViewData.TemplateInfo.htmlfieldPrefix da visualização. Assim:
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>
<textarea id="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" class="html">
<%= Model.ToString() %>
</textarea>
Para mostrar por que isso funciona, aqui está o lugar no modeloHelPers.cs (da fonte de visualização 1 do MVC2) em que o ViewData é inicializado para o Controle do Modelo do Editor:
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),
}
};
Na chamada acima, "Expression" é inicializado (mais adiante a pilha de chamadas) com o nome da propriedade que está sendo editada.
BTW, @sperling abaixo pegou um detalhe que eu perdi originalmente: se você está usando (ou pode usar) um não-defensor HtmlHelper.IdAttributeDotReplacement
, então você vai querer substituir os pontos no HtmlPrefix
propriedade com HtmlHelper.IdAttributeDotReplacement
.
Outras dicas
Usa isso para gerar ID (com o prefixo do modelo). Pule a parte .replace () se você deseja o atributo de nome.
<%=Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(String.Empty).Replace(".", HtmlHelper.IdAttributeDotReplacement) %>
No nosso caso, tivemos que usar Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName
com ExpressionHelper.GetExpressionText
que em Razor foi usado assim:
// 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"/>