ASP.NET MVC 3 中字典<字符串、字符串>的隐藏输入



我需要在 Post 操作中获取我的模型属性,所以需要为它们隐藏元素,但我对Dictionary <string, string>类型有问题。 这是我的模型:

public class ViewModel{
 ...
 public ViewPart ViewPart { get; set; }
}
public class ViewPart {
 ...
 public Dictionary<string, string> Flags { get; set; }
}

和我的控制器:

Dictionary<string, string> flags = new Dictionary<string, string>();
flags.Add("kind", "Edit");
flags.Add("Command", "Save");
ViewModel model = new ViewModel(){ Flags  = flags };
return View(model);

在视野中:

@foreach(var item in Model.ViewPart.Flags) { 
 <input type="hidden" id="ViewPart_Flags_@(item.Key)" value="@item.Value" name="ViewPart.Flags[@(item.Key)]" />
}

我也试试这个:

@foreach(var item in Model.ViewPart.Flags) { 
  @Html.HiddenFor(modelItem => item)
}

更新后操作:

[HttpPost]
public ActionResult MyPostAction(ViewModel model){
  //model.ViewPart.Flags is null
}

但是在后期操作中,Flags始终为空,为什么? 我的错在哪里?有没有更好的方法将变量从视图传递到操作?

如果要

模型绑定到字典,则需要两个隐藏字段,一个用于Key,一个用于Value

var index = 0;
foreach (var item in Model.ViewPart.Flags)
{
    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags[@(index)].Key"/>
    <input type="hidden" value="@item.Value" 
                         name="ViewPart.Flags[@(index)].Value"/>
    index++;
}
    <input type="submit" value="Save"/>

请注意,您还需要一个运行索引来使模型绑定器满意。

或者,如果您不想运行,可以使用额外的隐藏Index字段来解决:

foreach (var item in Model.ViewPart.Flags)
{
    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags.Index"/>
    <input type="hidden" value="@item.Key" 
                         name="ViewPart.Flags[@(item.Key)].Key" />
    <input type="hidden" value="@item.Value" 
                         name="ViewPart.Flags[@(item.Key)].Value" />
}
    <input type="submit" value="Save"/>
}

您可以在这两篇文章中找到有关与集合进行模型绑定的大量信息:

  • ASP.NET 用于将模型绑定到数组、列表、集合、字典的连线格式
  • 模型绑定到列表

将发布操作更改为此

[HttpPost]
public ActionResult MyPostAction(ViewModel model, ViewPart viewPart)
{
    model.ViewPart.Flags = viewPart.Flags;
}

并在视图中使用

@foreach(var item in Model.ViewPart.Flags) { 
  @Html.HiddenFor(modelItem => item)
}

如果这不起作用,请检查呈现的 HTML 的源代码,并查看是否呈现了隐藏信息。我不确定@Html.HiddenFor是否可以使用Dictionary如果它不起作用,您可能需要像以前一样写出来。