2011-01-19 37 views
2

我有一个属性为List的模型。 MyObjects只有一个ID,一个描述和一个选定的布尔属性。ASP.Net MVC从复选框列表中返回值

我设法在我的视图上显示项目作为复选框。我这样做了:

<%foreach (var cat in Model.DefaultCategories) 
     {%> 
    <tr> 
     <td> 
     <%=cat.Category %> 

     </td> 
     <td> 
      <%=Html.CheckBoxFor(x=>cat.Selected) %> 
     </td> 
    </tr> 
    <% 
     }%> 
</table> 

但是,有一个问题。当它们呈现时,它们都以相同的名字结束。以下是我的名单的一部分:

 <tr> 
     <td> 
     Medical 

     </td> 
     <td> 
      <input id="cat_Selected" name="cat.Selected" type="checkbox" value="true" /><input name="cat.Selected" type="hidden" value="false" /> 
     </td> 

    </tr> 

    <tr> 
     <td> 
     Salary 

     </td> 
     <td> 
      <input checked="checked" id="cat_Selected" name="cat.Selected" type="checkbox" value="true" /><input name="cat.Selected" type="hidden" value="false" /> 
     </td> 
    </tr> 

它们都被命名为“cat.Selected”。

我该如何解决这个问题?

然后,当我提交时,我需要遍历它们。用不同的名字,我认为我可以让他们在我的HttpPost方法中:

 [HttpPost] 
    public ActionResult Modify(int id, FormCollection formValues) 
    { 
     PayeeDto p = new PayeeDto { Name = Request.Form["name"], PayeeId = id }; 

     Services.PayeeServices.Save(p); 
     return RedirectToAction("Index"); 
    } 

FormCollection会有不同的名字吗?目前,它只有一个'cat.selected'项目。

回答

3

有一种方法可以使用的名称与[]提交收藏到你的动作。如这里所描述http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

<% for (int i = 0; i < Model.DefaultCategories.Count; i++) { %> 
<td> 
    <input type="checkbox" name="[<%= i %>].Selected" <% Model.DefaultCategories[i].Selected ? "checked=\"checked\"" : string.Empty %>/> 
</td> 
<% }%> 

那么你的行动可以采取的模型的集合,像这样

public ActionResult Modify(int id, ICollection<UpdateModel> updates) 
{} 
1

这可能不是最好的答案,但我尽量不使用MVC中生成的复选框。

我会改变

<td> 
    <%=Html.CheckBoxFor(x=>cat.Selected) %> 
</td> 

<td> 
    <input type="checkbox" name="<%: cat.value %>" id="<%: cat.value %>" <% cat.Selected ? " checked=\"checked\" " : ""; %> /> 
</td> 
2

我会建议你使用模板编辑器和停止你的意见编写循环。他们会照顾生成正确的名字,以便具有约束力的作品。例如:

在你的主观点:

<table> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Selected</th> 
     </tr> 
    </thead> 
    <tbody> 
     <%: Html.EditorFor(x => x.DefaultCategories) %> 
    </tbody> 
</table> 

,然后编辑模板内强类型的类别(~/Views/Home/EditorTemplates/Category.ascx)。另外,如果你想在控制器动作中获得相应的名字,你需要包含它(可能是隐藏字段)。另一种技术涉及增加只有ID,然后在你的控制器动作取回来从数据库中的相关信息:

<%@ Control 
    Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.Category>" %> 

<tr> 
    <td><%: Model.Name %></td> 
    <td> 
     <!-- include the category name as hidden field so that 
      we can fetch it back in the controller action 
     --> 
     <%: Html.HiddenFor(x => x.Name) %> 
     <%: Html.CheckBoxListFor(x => x.Selected) %> 
    </td> 
</tr> 

现在的命名规则是很重要的位置。如果视图模型上的DefaultCategories属性是IEnumerable<Category>,那么编辑器模板需要被称为Category.ascx并放置在~/Views/Home/EditorTemplates/Category.ascx中,或者如果它将在~/Views/Shared/EditorTemplates/Category.ascx中的多个控制器之间重用。

而且要提交到应该使用视图模型参数的控制器动作:

[HttpPost] 
public ActionResult Modify(MyViewModel model) 
{ 
    PayeeDto = Mapper.Map<MyViewModel, PayeeDto>(model); 
    Services.PayeeServices.Save(p); 
    return RedirectToAction("Index"); 
} 
+0

谢谢 - 你能也许解释Mapper.Map?听起来很有趣。 – Craig 2011-01-19 08:07:54