再次遇到一个“这不应该是这个?
问题:我想在MVC中使用一个表单来创建一个对象.对象的一个元素是一组有限的选择 – 一个下拉列表的完美候选者.
但是如果我在我的模型中使用一个SelectList,并在我的View中使用一个下拉列表,然后尝试将Model发回我的Create方法,我会收到错误“Missing Method Exception:No Parameterless constructor for this object”.探索MVC源代码,似乎为了绑定到模型,Binder必须能够先创建它,并且它不能创建SelectList,因为它没有默认构造函数.
以下是简化代码:
对于型号:
public class DemoCreateviewmodel { public SelectList Choice { get; set; } }
对于控制器:
// // GET: /Demo/Create public ActionResult Create() { DemoCreateviewmodel data = new DemoCreateviewmodel(); data.Choice = new SelectList(new string[] { "Choice1","Choice2","Choice3" }); ViewData.Model = data; return View(); } // // POST: /Demo/Create [HttpPost] public ActionResult Create(DemoCreateviewmodel form) { try { // TODO: Add insert logic here return RedirectToAction("Index"); } catch { return View(); } }
而对于视图:
<fieldset> <legend>Fields</legend> <%= Html.LabelFor(model => model.Choice) %> <%= Html.DropDownListFor(model => model.Choice,Model.Choice) %> <p> <input type="submit" value="Create" /> </p> </fieldset>
现在,我知道我可以通过退出10码并打开这个工作:绕过模型绑定并返回到FormCollection,并自动验证并绑定所有的字段,但是必须要简单一些.我的意思是说,这是一个简单的要求.有没有办法使这项工作在MVC ModelBinding架构中?如果是这样,那是什么?如果没有,怎么来?
编辑:嗯,我的脸上有蛋,但也许这会帮助别人.我做了一些更多的实验,发现一个似乎有效的简单解决方案.
提供一个简单的值(字符串或整数,取决于您的选择列表值类型),并将其命名为绑定到的模型元素.然后提供第二个元素作为选择列表,并将其命名为其他内容.所以我的模型变成了
public class DemoCreateviewmodel { public string Choice { get; set; } public SelectList Choices { get; set; } }
然后View中的DropDownListFor语句变为:
<%= Html.DropDownListFor(model => model.Choice,Model.Choices) %>
当我这样做时,提交按钮将表单中所做的选择正确地绑定到字符串Choice,并将模型提交回第二个Create方法.