I have an editor template whose job is to take a SelectList as its model and build a select element in html using the Html.DropDownList() helper extension.
I'm trying to assign the name attribute for the select based on a ModelMetadata property. (Reason: on post-back, I need to bind to an object that has a different property name for this item than the ViewModel used to populate the form.)
The problem I'm running into is that DropDownList() is appending the name I'm providing instead of replacing it, so I end up with names like categories.category instead of category.
Here is some code for you to look at...
SelectList.ascx
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<System.Web.Mvc.SelectList>" %>
<%= Html.DropDownList(
(string)ViewData.ModelMetadata.AdditionalValues["PropertyName"], Model) %>
...which resulted in "SkillLevel" (not "SkillLevels.SkillLevel"), proving that the data stored in metadata is correct.
and
<%= Html.DropDownList(
(string)ViewData.ModelMetadata.AdditionalValues["PropertyName"], Model,
new { name = (string)ViewData.ModelMetadata.AdditionalValues["PropertyName"] }) %>
...which still resulted in <select name=SkillLevels.Skilllevel>.
Questions
What's going on here? Why does it append the name instead of just using it? Can you suggest a good workaround?
Update:
I ended up writing a helper extension that literally does a find/replace on the html text:
public static MvcHtmlString BindableDropDownListForModel(this HtmlHelper helper)
{
var propertyName = (string)helper.ViewData.ModelMetadata.AdditionalValues["PropertyName"];
var compositeName = helper.ViewData.ModelMetadata.PropertyName + "." + propertyName;
var rawHtml = helper.DropDownList(propertyName, (SelectList)helper.ViewData.Model);
var bindableHtml = rawHtml.ToString().Replace(compositeName, propertyName);
return MvcHtmlString.Create(bindableHtml);
}
>>> I'd still like to understand why this workaround is necessary. Why does the select element's get assigned a composite name rather than the exact name I provide?
I have struggled with the MVC drop down - it just does not act right. So, I just roll my own html with a foreach on my model data. That may not be an acceptable workaround for you but MVC is flexible on purpose.
Disclaimer: I am not sure if this is totally safe and wont break anything.
But I faced the exact same situation. However, once i set ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty ,
the problem went away. This behavior seems to be by design inside of custom templates - take a look at ViewData.TemplateInfo.GetFullHtmlFieldName for example.
发布评论
评论(2)
我一直在努力解决 MVC 下拉菜单 - 它的行为不正确。所以,我只是在我的模型数据上使用 foreach 滚动我自己的 html。这对您来说可能不是一个可以接受的解决方法,但 MVC 是有意灵活的。
I have struggled with the MVC drop down - it just does not act right. So, I just roll my own html with a foreach on my model data. That may not be an acceptable workaround for you but MVC is flexible on purpose.
免责声明:我不确定这是否完全安全并且不会破坏任何东西。
但我面临着完全相同的情况。但是,一旦我设置
ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty
,问题就消失了。此行为似乎是自定义模板内部设计的 - 例如,请查看 ViewData.TemplateInfo.GetFullHtmlFieldName。
Disclaimer: I am not sure if this is totally safe and wont break anything.
But I faced the exact same situation. However, once i set
ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty
,the problem went away. This behavior seems to be by design inside of custom templates - take a look at
ViewData.TemplateInfo.GetFullHtmlFieldName
for example.