2010-05-26 2 views
10

다시 한번 "This should be this? *! # hard"상황에 직면했습니다.MVC에서 SelectList에 바인딩

문제점 : MVC에서 개체를 만드는 데 양식을 사용하고 싶습니다. 객체의 요소 중 하나는 드롭 다운 목록의 완벽한 후보 인 제한된 선택 집합입니다.

그러나 내 모델에서 SelectList를 사용하고 내 View의 드롭 다운 목록을 사용하여 모델을 내 Create 메서드에 다시 게시하려고하면 "누락 된 메서드 예외 : No 매개 변수없는 생성자가 있습니다. 목적". MVC 소스 코드를 살펴보면, 모델에 바인딩하기 위해 바인더가 먼저 생성 할 수 있어야하고, 기본 생성자가 없기 때문에 SelectList를 만들 수 없다는 것을 알 수 있습니다. 컨트롤러에 대한

public class DemoCreateViewModel 
{ 
    public SelectList Choice { get; set; } 
} 

: 모델의 경우 :

다음은 간단한 코드의

// 
// 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(); 
    } 
} 

그리고보기 위해 : 이제

<fieldset> 
    <legend>Fields</legend> 
    <%= Html.LabelFor(model => model.Choice) %> 
    <%= Html.DropDownListFor(model => model.Choice, Model.Choice) %> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 

, 나는 내가 할 수있는 알고 10 야드를 뒤로 젖히고 펀칭하여이 작업을하십시오 : 모델 바인딩을 우회하여 FormCo로 다시 떨어 뜨립니다. llection을 선택하고 모든 필드를 직접 확인하고 바인딩해야하지만 더 간단한 방법이 있어야합니다. 내 말은, 이것은 얻는만큼 간단한 요구 사항에 관한 것입니다. MVC ModelBinding 아키텍처 내에서이 작업을 수행 할 수있는 방법이 있습니까? 그렇다면 무엇입니까? 그리고 그렇지 않다면 어째서?

편집 : 글쎄, 난 얼굴에 난이 있지만 어쩌면 다른 사람을 도울 것입니다. 좀 더 실험을하고 간단한 해결책을 찾았습니다.

간단한 값 (선택 목록 값 유형에 따라 문자열 또는 정수)을 입력하고 바인딩 할 모델 요소의 이름을 지정하십시오. 그런 다음 선택 목록으로 두 번째 요소를 제공하고 다른 이름을 지정합니다. 나는이 작업을 수행 할 때

<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %> 

이 제출 버튼이 올바르게 선택 문자열 형태로 만든 검색을 결합 :

public class DemoCreateViewModel 
{ 
    public string Choice { get; set; } 
    public SelectList Choices { get; set; } 
} 

을 다음보기에서 DropDownListFor 문이된다 : 그래서 내 모델이되었다 모델을 두 번째 Create 메서드에 다시 제출합니다. 내 selectList의를 포함 할 ViewBag를 사용

@Html.DropDownListFor(model => model.Choice, 
         ViewBag.Choices as SelectList, 
         "-- Select an option--", 
         new { @class = "editor-textbox" }) 

주의 사항 :

+0

수정 사항을 게시 주셔서 감사합니다. 비슷한 문제가 발생하여 편집이 도움이되었습니다. – Chris

+0

대신 IEnumerable 또는 SelectListItems 목록에 바인딩 할 수 있습니까? –

답변

5

여기에 한 가지 방법입니다. 이렇게하면 다시 게시 할 때 클라이언트가 전체 선택 목록을 서버의 일부로 모델의 일부로 보내지 않습니다. 그런 다음

  public class DemoCreateViewModelForUpdate 
      { 
       public string Choice { get; set; } 
      } 

수행 할 수 있습니다

ViewBag.Choices = new SelectList(.... 
+1

* ViewList를 사용하여 SelectList를 포함하고 있습니다. 이 방법을 사용하면 게시자가 모델의 일부로 전체 선택 목록을 서버에 보내지 않습니다. * (1) 어쨌든 그렇게하지 않습니다. (2) ViewBag를 사용하면 게시가 중단되지 않고 모델에 바인딩되는 것을 막을 수 있습니다. –

0

이 selectList의 속성없이 포스트 조치에 대한 다른보기 모델을 만드는 고려해 컨트롤러 코드에서

, 당신은 단지보기 가방을 설정해야 모델 상태가 유효하지 않고 뷰를 다시 표시하려는 경우 항상 DemoCreateViewModelPost 인스턴스에서 DemoCreateViewModel 인스턴스로 매핑하십시오.내보기보기 모델 클래스에보기에 필요한 모든 것을 선호하는 경향이 있으므로 별도의보기 전용보기 모델을 사용하여 서버에 대한 여행을 위해 슬림하고 트림을 유지하도록하겠습니다. 보기에

, 당신은 할 줄 :
  @Html.DropDownListFor(m => m.Choice, Model.Choices) 

이전의 대답으로, 그래서 불필요한 데이터는 여행을 반올림하지 않을 것이다.

관련 문제