C#-使用EditorTemplate时出现ID和名称错误
作者:互联网
我花了大约3个小时来确定为什么发生以下(解释的)错误;最后,我确定这是MVC错误.我想问一下您的意见.
我创建了一个编辑器模板,并将其放在〜/ Shared / EditorTemplates文件夹下.而且我谨慎地使用了文件名,使其与类型名相同(因为我不想将第二个参数与“ @ Html.EditorFor”帮助器方法一起使用).结果,编辑器模板运行良好:除了回发;我肯定无法从模型中获取值,因为模型始终为空.我试图更改ID&输入并仔细选择名称,然后回发帖子:它工作正常.
所以;问题是:当我使用editorTemplate时,它以“ Question.[0] .QuestionContext”作为名称,并以“ Question__0_QuestionContext”作为输入和选择的ID;但是我希望以“ Question [0] .QuestionContext”作为名称,并以“ Question_0__QuestionContext”作为id.
然后我意识到我在EditorTemplate中使用@foreach.然后我切换回@for,但没有任何改变.您可以在下面找到模板:
@using DenemeMvc3Application3.Helpers;
@model DenemeMvc3Application3.Controllers.LocalizedNameViewModels
<table>
<thead>
<tr>
<td>@Html.LabelFor(modelItem => modelItem.ElementAtOrDefault(0).LanguageDropDownList)</td>
<td>@Html.LabelFor(modelItem => modelItem.ElementAtOrDefault(0).Value)</td>
</tr>
</thead>
<tbody>
@for (int index = 0; index < Model.Count; index++)
{
@Html.EditorFor(modelItem => modelItem[index])
}
</tbody>
</table>
因此,我通过在editortemplate&模板之外声明了foreach循环,将模板更改为更简单的模板.在视图内部并且仅对单个项目使用编辑器模板.而且有效.因此,我对使用反射器在mvc3上的模板工作原理进行了小小的研究.我发现了我认为的错误:
该问题是由System.Web.Mvc.TemplateInfo类的公共字符串GetFullHtmlFieldName(string partialFieldName)方法引起的,该方法由System.Web.Mvc.Html.SelectExtensions类的私有静态MvcHtmlString SelectInternal(此HtmlHelper htmlHelper,字符串optionLabel,字符串名称, IEnumerable selectList,bool allowMultiple,IDictionary htmlAttributes)方法.
因此,每当我们在EditorTemplate的foreach或for循环内使用@ Html.DropDownListFor(/ blah blah /)时,都会收到错误消息.
我还想向您展示下面的错误代码以进行说明:
// TemplateInfo method
public string GetFullHtmlFieldName(string partialFieldName)
{
/*Here's the extra dot: causing the error.*/
return (this.HtmlFieldPrefix + "." + (partialFieldName ?? string.Empty)).Trim(new char[] { '.' });
}
// SelectExtensions method
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
/* blah blah */
string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
/* blah blah */
}
// SelectExtensions method -> @Html.DropDownListFor
private static MvcHtmlString DropDownListHelper(HtmlHelper htmlHelper, string expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
{
return htmlHelper.SelectInternal(optionLabel, expression, selectList, false, htmlAttributes);
所以你的想法是什么?
解决方法:
Then I realized that I was using @foreach inside the EditorTemplate.
Then I switch back to @for but nothing changed.
如何摆脱所有循环并简单地:
@model IEnumerable<FooViewModel>
<table>
<thead>
<tr>
<td>@Html.LabelFor(modelItem => modelItem.ElementAtOrDefault(0).LanguageDropDownList)</td>
<td>@Html.LabelFor(modelItem => modelItem.ElementAtOrDefault(0).Value)</td>
</tr>
</thead>
<tbody>
@Html.EditorForModel()
</tbody>
</table>
好多了?没有循环,正确的名称和ID.这是ASP.NET MVC,它将为模型集合的每个元素自动呈现编辑器模板.
以及相应的编辑器模板(〜/ Views / Shared / EditorTemplates / FooViewModel.cshtml):
@model FooViewModel
<tr>
<td>@Html.EditorFor(x => x.SomeProperty)</td>
<td>@Html.EditorFor(x => x.SomeOtherProperty)</td>
</tr>
标签:asp-net,c,net,asp-net-mvc-3 来源: https://codeday.me/bug/20191201/2082153.html