将SelectList通过ViewData传递给编辑器模板 - 未正确显示

时间:2010-12-06 11:49:58

标签: asp.net-mvc templates drop-down-menu

这有点复杂所以忍受我。

假设我有一个控制器编辑操作的示例,定义如下:

Node nd = _repo.getNode(id);

List<Category> ac = new List<Category>();
ac.AddRange(_repo.getCategories());
SelectList acl = new SelectList(ac, "category_id", "category_name", ac.Where(cat => cat.category_id == nd.category_id).First());

ViewData["category_id"] = acl;

return View(nd);

视图模仿如下:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Myapp.Models.Node>" %>
<% if (ViewData.TemplateInfo.TemplateDepth > 1) 
   { %>
<%= ViewData.ModelMetadata.SimpleDisplayText %>
<% }
   else
   { %>
<table cellpadding="0" cellspacing="0" border="0">
    <% foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
       { %>
    <% if (prop.HideSurroundingHtml)
       { %>
    <%= Html.Editor(prop.PropertyName) %>
    <% }
       else
       { %>

    <tr>
        <td>
            <div class="editor-label" style="text-align: right;">
                <%= prop.IsRequired ? "*" : ""%>
                <%= Html.Label(prop.PropertyName)%>
            </div>
        </td>
        <td>
            <div class="editor-field">
                <% if (ViewData.Keys.Contains(prop.PropertyName))
                   {
                       if ((ViewData[prop.PropertyName]).GetType().Name == "SelectList")
                            { %>
                                <%= Html.DropDownList(prop.PropertyName, (SelectList)ViewData[prop.PropertyName])%>
                            <% }
                                else
                                    { %>
                                        <%= Html.Editor(prop.PropertyName)%>
                                    <% } %>                       
                  <% }
                   else
                   { %>
                <%= Html.Editor(prop.PropertyName)%>
                <% } %>
                <%= Html.ValidationMessage(prop.PropertyName, "*")%>
            </div>
        </td>
    </tr>

    <% } %>
    <% } %>
</table>
<% } %>

因此,模板的作用是显示ViewData["property_name"]存在的每个属性的下拉列表。

我还为Node类的每个属性定义了DisplayName个元数据属性。

现在,下拉列表显示正常并且正在正确填充,但是:

  1. 始终选择列表中的第一个值,即使SelectList选择值谓词很好并且设置了正确的值(至少在调试器中)。
  2. 模板中的Html.Label为属性返回正确的DisplayName,但是当我为它们定义ViewData以显示下拉列表时,标签将重置为普通属性名称(即。category_id而不是{ {1}})。
  3. 是什么给出的?你能想到任何“整洁”的方式来实现这个功能吗?

1 个答案:

答案 0 :(得分:1)

好吧,没有人回答,所以我的答案是肯定的,也许这对某人来说很方便:

不要使用ViewData键的属性名称!它与视图模型混淆,因此您的视图会混淆并开始表现得很奇怪。

实际上,最好完全避免魔法字符串混乱,但如果你坚持,只需使用像ex.: ViewData[prop.PropertyName+"_list"]这样的东西。你的意见现在会好起来的。