MVC3 Html.Editor目标字典没有绑定到客户端

时间:2011-03-24 19:46:01

标签: asp.net-mvc-3 dictionary model-binding

我的视图模型与

一致
EditViewModel
    SomeUserType User
        Dictionary<string, string> Claims

在我看来,我试图将其绑定如下

@{
    int i = 0;
    foreach (var key in Model.User.Claims.Keys)
    {                                                                       
            <div class="editor">
                <input type="hidden" value="@i" name="User.Claims.Index">
                <div class="editor-label">
                    @Html.Label(string.Format("User.Claims[{0}].Key", i))
                </div>
                <div class="editor-field">
                    @Html.Editor(string.Format("User.Claims[{0}].Key", i))
                </div>
                <div class="editor-label">
                    @Html.Label(string.Format("User.Claims[{0}].Value", i))
                </div>
                <div class="editor-field">
                    @Html.Editor(string.Format("User.Claims[{0}].Value", i))
                </div>
            </div>    
        i++;
    }
}

如我所料,它会在编辑屏幕上呈现一系列键值对文本框。但是,即使在Claims词典中有KeyValuePairs,文本框也总是空的。

如果我填写KVP文本框的值并将表单发回给我的控制器,我会将正确的值模型绑定回我的User.Claims字典。

我错过了什么阻止绑定在视图加载时具有正确的值?

编辑:其他信息,基本上我正在试图弄清楚这对MVC本身是如何运作的。我直接从核心MVC(2)对象模板Brad Wilson discusses here创建了我的视图。我试图在Razor中找到相应的确切代码,但我根本无法找到它...离题...转换为Razor我最终得到了

@if (ViewData.TemplateInfo.TemplateDepth > 4) 
{
    @ViewData.ModelMetadata.SimpleDisplayText
}
else
{
    <div class="editor">    
        @foreach (var prop in ViewData.ModelMetadata.Properties
            .Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm)))
        {                        

            if (prop.HideSurroundingHtml)
            {
            @Html.Editor(prop.PropertyName)
            }
            else
            {
                if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName)
                                                            .ToHtmlString()))
                {
                    <div class="editor-label"> @Html.Label(prop.PropertyName) 
                    </div>
                }

                <div class="editor-field">
                    @Html.Editor(prop.PropertyName)
                    @Html.ValidationMessage(prop.PropertyName)
                </div>            
            }
        }
    </div>    
}

主要区别在于对@if (ViewData.TemplateInfo.TemplateDepth > 4)的编辑,这将允许MVC深入到足以使其到达我的字典,然后它可以正确地绑定所有内容。然而,在进一步询问调试时,我看到它绑定Key属性时它实际上只看到@Html.Editor("Key")这是如何工作的?

显然,编辑必须具备ViewData.ModelMetadata.Properties的某种知识,然而它确定了ViewData.TemplateInfo.Visited()的结果,它能够正确放置正确的东西,就在这时我正处于失去了幕后发生的事情,在这个foreach循环内部,@ Html.Editor(“Key”)做任何事情。

3 个答案:

答案 0 :(得分:3)

试试这样:

@{
    var i = 0;
    foreach (var key in Model.User.Claims.Keys)
    {
        <div class="editor">
            <input type="hidden" value="@i" name="User.Claims.Index" />
            <div class="editor-label">
                @Html.Label(string.Format("User.Claims[{0}].Key", i))
            </div>
            <div class="editor-field">
                @Html.TextBox(string.Format("User.Claims[{0}].Key", i), key)
            </div>
            <div class="editor-label">
                @Html.Label(string.Format("User.Claims[{0}].Value", i))
            </div>
            <div class="editor-field">
                @Html.TextBox(string.Format("User.Claims[{0}].Value", i), Model.User.Claims[key])
            </div>
        </div>            
        i++;
    }
}

答案 1 :(得分:2)

@ Html.Editor(字符串名称)将为 ViewData 中的字段名称生成编辑器。如果ViewData不包含您的对象,则必须使用另一个重载:@ Html.Editor(string name,object viewData)。

在你的情况下,你可以用@ Html.Label替换@ Html.Label(string.Format(“User.Claims [{0}]。Key”,i))(string.Format(“User.Claims [ {0}]。键“,i),User.Claims [i] .Value)

答案 2 :(得分:0)

   @{
 foreach (KeyValuePair<string, string> item  in Model.ShippingCarrier)
 {
    <tr>
    <td>
   @Html.TextBox(item.Key.ToString(), item.Key, new { @class = "w50" }) : @Html.TextBox(item.Key.ToString(), item.Key, new { @class = "w50" }) 
    </td>
   </tr>

 }
    }