Dav*_*nna 11 asp.net-mvc model-binding selectlist
我再一次面对"这不应该是这个?*!#hard"的情况.
问题:我想在MVC中使用表单来创建对象.对象的一个元素是一组有限的选择 - 下拉列表的完美候选者.
但是如果我在我的模型中使用SelectList,并在我的View中使用下拉列表,然后尝试将模型发布回我的Create方法,则会收到错误"Missing Method Exception:No Parameterless constructor for this object".探索MVC源代码,似乎为了绑定到模型,Binder必须能够首先创建它,并且它不能创建SelectList,因为它没有默认的构造函数.
这是简化的代码:对于模型:
public class DemoCreateViewModel
{
public SelectList Choice { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
对于控制器:
//
// 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();
}
}
Run Code Online (Sandbox Code Playgroud)
对于视图:
<fieldset>
<legend>Fields</legend>
<%= Html.LabelFor(model => model.Choice) %>
<%= Html.DropDownListFor(model => model.Choice, Model.Choice) %>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
Run Code Online (Sandbox Code Playgroud)
现在,我知道我可以通过退回10码和踢出来做这项工作:绕过模型绑定并回退到FormCollection并自己验证并绑定所有字段,但必须有一个更简单的方法.我的意思是,这只是一个简单的要求.有没有办法在MVC ModelBinding架构中实现这项工作?如果是这样,它是什么?如果没有,怎么样?
编辑:嗯,我脸上有鸡蛋,但也许这会帮助别人.我做了一些实验,发现了一个似乎有效的简单解决方案.
提供一个简单的值(字符串或整数,具体取决于您的选择列表值类型),并将其命名为您绑定的模型元素.然后提供第二个元素作为选择的选择列表,并将其命名为其他元素.所以我的模型成了:
public class DemoCreateViewModel
{
public string Choice { get; set; }
public SelectList Choices { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后View中的DropDownListFor语句变为:
<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %>
Run Code Online (Sandbox Code Playgroud)
当我这样做时,提交按钮正确地将表单中的选择绑定到字符串Choice,并将模型提交回第二个Create方法.
这是一种方法:
@Html.DropDownListFor(model => model.Choice,
ViewBag.Choices as SelectList,
"-- Select an option--",
new { @class = "editor-textbox" })
Run Code Online (Sandbox Code Playgroud)
请注意,我使用ViewBag来包含我的SelectList.这样,当您回发时,客户端不会将整个选择列表作为模型的一部分发送到服务器.
在您的控制器代码中,您只需要设置视图包:
ViewBag.Choices = new SelectList(....
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15822 次 |
| 最近记录: |