2011-01-19 7 views
2

목록 인 속성이있는 모델이 있습니다. MyObjects는 단순히 id, description 및 선택된 부울 속성을가집니다.체크 박스 목록에서 값을 반환하는 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는 다른 이름을 가질 것인가? 현재로서는 '고양이 선택 항목'이 하나뿐입니다.

답변

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

+0

@cdotlister에서 [AutoMapper] (http://automapper.codeplex.com/)를 살펴보십시오. 그러나 이것은 당신이 사용할 수있는 어떤 매핑 기술이 될 수도 있습니다 (수동으로 작성한 것조차도). 컨트롤러 액션은 뷰 모델을 모델로 매핑하여 리포지토리에 전달해야하는 매개 변수로 받아야합니다. 이 매핑이 어떻게 발생하는지에 대해서는 여기에서 다루지 않습니다. –

관련 문제