2011-01-19 36 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