如何为ASP.NET MVC上的GET和POST操作绑定字典类型参数(How to bind Dictionary type parameter for both GET and POST action on ASP.NET MVC)

我想定义一个显示标签和复选框列表的视图,用户可以更改复选框,然后回发。 我在回复字典时遇到问题。 也就是说,post方法的字典参数为null。

以下是GET和POST操作的操作方法:

public ActionResult MasterEdit(int id) { Dictionary<string, bool> kv = new Dictionary<string, bool>() { {"A", true}, {"B", false} }; return View(kv); } [HttpPost] public ActionResult MasterEdit(Dictionary<string, bool> kv) { return RedirectToAction("MasterEdit", new { id = 1 }); }

Beliw是观点

@model System.Collections.Generic.Dictionary<string, bool> @{ ViewBag.Title = "Edit"; } <h2> MasterEdit</h2> @using (Html.BeginForm()) { <table> @foreach(var dic in Model) { <tr> @dic.Key <input type="checkbox" name="kv" value="@dic.Value" /> </tr> } </table> <input type="submit" value="Save" /> }

任何想法将非常感激!

I want to define a view which displays a list of label and checkbox, user can change the checkbox, then post back. I have problem posting back the dictionary. That is, The dictionary parameter for the post method is null.

Below are action method for both GET and POST action:

public ActionResult MasterEdit(int id) { Dictionary<string, bool> kv = new Dictionary<string, bool>() { {"A", true}, {"B", false} }; return View(kv); } [HttpPost] public ActionResult MasterEdit(Dictionary<string, bool> kv) { return RedirectToAction("MasterEdit", new { id = 1 }); }

Beliw is the view

@model System.Collections.Generic.Dictionary<string, bool> @{ ViewBag.Title = "Edit"; } <h2> MasterEdit</h2> @using (Html.BeginForm()) { <table> @foreach(var dic in Model) { <tr> @dic.Key <input type="checkbox" name="kv" value="@dic.Value" /> </tr> } </table> <input type="submit" value="Save" /> }

Any idea would be very much appreciated!

最满意答案

不要为此使用字典。 模型绑定效果不佳。 可能是PITA。

视图模型会更合适:

public class MyViewModel { public string Id { get; set; } public bool Checked { get; set; } }

然后一个控制器:

public class HomeController : Controller { public ActionResult Index() { var model = new[] { new MyViewModel { Id = "A", Checked = true }, new MyViewModel { Id = "B", Checked = false }, }; return View(model); } [HttpPost] public ActionResult Index(IEnumerable<MyViewModel> model) { return View(model); } }

然后是相应的视图( ~/Views/Home/Index.cshtml ):

@model IEnumerable<MyViewModel> @using (Html.BeginForm()) { <table> <thead> <tr> <th></th> </tr> </thead> <tbody> @Html.EditorForModel() </tbody> </table> <input type="submit" value="Save" /> }

最后是相应的编辑器模板( ~/Views/Home/EditorTemplates/MyViewModel.cshtml ):

@model MyViewModel <tr> <td> @Html.HiddenFor(x => x.Id) @Html.CheckBoxFor(x => x.Checked) @Html.DisplayFor(x => x.Id) </td> </tr>

Don't use a dictionary for this. They don't play well with model binding. Could be a PITA.

A view model would be more appropriate:

public class MyViewModel { public string Id { get; set; } public bool Checked { get; set; } }

then a controller:

public class HomeController : Controller { public ActionResult Index() { var model = new[] { new MyViewModel { Id = "A", Checked = true }, new MyViewModel { Id = "B", Checked = false }, }; return View(model); } [HttpPost] public ActionResult Index(IEnumerable<MyViewModel> model) { return View(model); } }

then a corresponding view (~/Views/Home/Index.cshtml):

@model IEnumerable<MyViewModel> @using (Html.BeginForm()) { <table> <thead> <tr> <th></th> </tr> </thead> <tbody> @Html.EditorForModel() </tbody> </table> <input type="submit" value="Save" /> }

and finally the corresponding editor template (~/Views/Home/EditorTemplates/MyViewModel.cshtml):

@model MyViewModel <tr> <td> @Html.HiddenFor(x => x.Id) @Html.CheckBoxFor(x => x.Checked) @Html.DisplayFor(x => x.Id) </td> </tr>

更多推荐