2011-01-19 10 views
2

私はListであるプロパティを持つモデルを持っています。 MyObjectsには、id、description、および選択されたbooleanプロパティがあります。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

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

を変更します。ここ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> 
    <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)に入力しました。また、対応するNameをコントローラのアクションに戻したい場合は、それを(おそらく隠しフィールドとして)含める必要があります。別の方法では、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

+0

@cdotlister、[AutoMapper](http://automapper.codeplex.com/)をご覧ください。しかし、これはあなたが使用できる任意のマッピングテクニック(あなたが手作業で書いたものでさえ)かもしれません。コントローラのアクションは、モデルにマッピングしてリポジトリに渡す必要があるパラメータとしてビューモデルを受け取る必要があるという考えがあります。このマッピングがどのように起こるかは、ここで話題とは別です。 –

関連する問題