?" />

为什么 Html.DropDownList() 产生

发布于 2024-08-22 04:00:53 字数 2654 浏览 9 评论 0 原文

我有一个编辑器模板,其工作是将 SelectList 作为其模型,并使用 Html.DropDownList() 在 html 中构建 select 元素助手扩展。

我试图根据 ModelMetadata 属性为 select 分配 name 属性。 (原因:在回发时,我需要绑定到一个对象,该对象的属性名称与用于填充表单的 ViewModel 不同。)

我遇到的问题是 DropDownList()< /code> 是追加我提供的名称,而不是替换它,因此我最终得到的名称是 categories.category 而不是 <代码>类别

以下是一些代码供您查看...

SelectList.ascx

<%@ Control Language="C#"
    Inherits="System.Web.Mvc.ViewUserControl<System.Web.Mvc.SelectList>" %>
<%= Html.DropDownList(
    (string)ViewData.ModelMetadata.AdditionalValues["PropertyName"], Model) %>

结果 HTML

<select id="SkillLevels_SkillLevel" name="SkillLevels.SkillLevel">
    <option value="1">High</option>
    <option value="2">Med</option>
    <option selected="selected" value="3">Low</option>
</select>

预期 HTML

<select id="SkillLevels_SkillLevel" name="SkillLevel">
    <option value="1">High</option>
    <option value="2">Med</option>
    <option selected="selected" value="3">Low</option>
</select>

也尝试过

<%= Html.Encode((string)ViewData.ModelMetadata.AdditionalValues["PropertyName"])%>

。 ..结果是“SkillLevel”(不是“SkillLevels.SkillLevel”),证明元数据中存储的数据是正确的。

...

<%= Html.DropDownList(
    (string)ViewData.ModelMetadata.AdditionalValues["PropertyName"], Model,
    new { name = (string)ViewData.ModelMetadata.AdditionalValues["PropertyName"] }) %>

这仍然导致

问题

这是怎么回事?为什么它附加名称而不是仅仅使用它?你能建议一个好的解决方法吗?

更新:

我最终编写了一个帮助程序扩展,它实际上对 html 文本进行查找/替换:

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);
}

>>> 我仍然想了解为什么会这样解决方法是必要的。为什么 select 元素被分配一个复合名称而不是我提供的确切名称?

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) %>

Resulting HTML

<select id="SkillLevels_SkillLevel" name="SkillLevels.SkillLevel">
    <option value="1">High</option>
    <option value="2">Med</option>
    <option selected="selected" value="3">Low</option>
</select>

Expected HTML

<select id="SkillLevels_SkillLevel" name="SkillLevel">
    <option value="1">High</option>
    <option value="2">Med</option>
    <option selected="selected" value="3">Low</option>
</select>

Also tried

<%= Html.Encode((string)ViewData.ModelMetadata.AdditionalValues["PropertyName"])%>

...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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

没有你我更好 2024-08-29 04:00:53

我一直在努力解决 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.

站稳脚跟 2024-08-29 04:00:53

免责声明:我不确定这是否完全安全并且不会破坏任何东西。
但我面临着完全相同的情况。但是,一旦我设置
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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文