2012-04-23 4 views
2

컨트롤러로 돌아 가기 위해 필요한 여러 행의 데이터가있는 테이블이 있습니다. 필자는 처음에는 시간대를 선택하고 버튼을 클릭하여 표를로드합니다. 테이블은 모든 관련 레코드를로드하지만 내 테이블 셀 중 하나에는 드롭 다운 목록이 있습니다. 따라서 드롭 다운에서 "업데이트"를 클릭하면 내 컨트롤러가 변경 사항을 저장할 수 있습니다.MVC : 컨트롤러에 여러 행의 데이터 반환

내가 시도하고 저장할 때까지 모든 것이 작동합니다. 컨트롤러에 전송 된 모델은 완전히 null입니다. 테이블 셀에 연결된 목록 속성은 컨트롤러 null로 반환됩니다.

@ModelType SuperViewModel 
//We need this a view model in order to store a List of the models in the table 

@Using (Html.BeginForm()) 
@For Each i in Model.CompleteList 
    Dim currentItem = i //MVC auto-generated extra declarations. Seems redundant to me but it works. 
@<table> 
<tr> 
<td>@Html.DisplayFor(function(Model)currentItem.Name)</td> 
<td>@Html.DisplayFor(function(Model)currentItem.SampleTime)</td> 
<td>@Html.DropDownListFor(function(Model)currentItem.WorkTime, ViewBag.WorkTimeList)</td> 
</tr> 
Next 
</table> 
<input name="submit" type="submit" value="Update"/> 
End Using 

//Controller 
<HttpPost()> 
function Save(vmodel as SuperViewModel, submit as String) as ActionResult //NOTE: submit parameter is used because we have two submit buttons but its not relevant here 
     if submit = "Update" 
      db.Entry(vmodel.CompleteList).State = EntityState.Modified//Here the exception is throw because our list is null at this point even tho its tied to the model in the view. 
      db.SaveChanges() 
     end if 
End Function 

참고 : 이것은 VB.NET로 작성되었지만 C# 도움말을 환영합니다. MVC에서 두 언어에 익숙합니다.

+0

SuperViewModel은 어떻게 정의됩니까? –

+0

여기에는 여러 속성이 있지만 여기에 적용되는 속성은 List (Of AnotherModel) 인 "CompleteList"입니다. Entity Framework에서 DB 테이블을 기반으로 생성 한 다른 모델 – ExceptionLimeCat

+0

'끝내기 '전에'다음'이 누락되어'For Each'를 닫습니까? 또한보기에서 렌더링 한 마크 업을 추가 할 수 있습니까? –

답변

2

이터레이터에 대해 a를 사용하고 뷰에서 HTML 요소에 대해 색인 된 요소를 사용해야합니다. VB.NET 구문을 모르지만, C# 예제는 아래에 있습니다. 이렇게하면 모델 바인더가 뷰 모델의 요소를 올바르게 결정하여 다시 게시 할 때 뷰 모델을 다시 채울 수 있습니다.

<table> 
@For(var i = 0; i < Model.CompleteList.Count; i++) 
{ 
<tr> 
<td>@Html.DisplayFor(Model.CompleteList[i].Name)</td> 
<td>@Html.DisplayFor(Model.CompleteList[i]..SampleTime)</td> 
<td>@Html.DropDownListFor(Model.CompleteList[i]..WorkTime, ViewBag.WorkTimeList)</td> 
</tr> 
} 
</table> 

그러면 게시 방법이 정상적으로 작동합니다.

+0

올바른 내용입니다. 목록에있는 특정 인스턴스에 행을 바인딩하지 않았습니다. 감사. – ExceptionLimeCat

0

매개 변수 이름의 충돌로 인해 null이 반환 될 수 있습니다 (사용 된 매개 변수 이름은 다른 곳에서도 사용되어야합니다). 보십시오이

<input name="subButton" type="submit" value="Update"/> 

변경

function Save(vm as SuperViewModel, subButton as String) as ActionResult 
+0

그게 작동하지 않습니다. 컨트롤러를 눌렀을 때 SuperViewModel은 여전히 ​​null입니다. – ExceptionLimeCat

+0

[블로그 게시물] (http://codeblog.shawson.co.uk/mvc-strongly-typed-view-returns-a-null-model-on-post-back/)을 참조하십시오. –

+0

그 블로그는 그렇지 않았습니다. 정말 도움이됩니다. ModelState 유효성 검사를 추가했습니다. 뷰 모델이 여전히 null 인 경우이를 전달합니다. – ExceptionLimeCat

0

, 나는 DropDownListFor에 의해 생성 된 마크 업에 이름을 볼 필요가있을 것이다,하지만 난 currentItem 당신이 CompleteList 유형에 대해 구속력이 있기 때문에 의심하지만, 귀하의 컨트롤러 방법은 전체 SuperViewModel 유형을 기대하고 있습니다. 코드에는 아무 것도 없으므로 SuperViewModel 유형에 바인딩 된 것으로 나타났습니다.

은 당신의 컨트롤러 방법을 변경해보십시오 :

<HttpPost()> 
function Save(currentItem as CompleteList, submit as String) as ActionResult //NOTE: submit parameter is used because we have two submit buttons but its not relevant here 
     if submit = "Update" 
      db.Entry(vmodel).State = EntityState.Modified//Here the exception is throw because our list is null at this point even tho its tied to the model in the view. 
      db.SaveChanges() 
     end if 
End Function 

WorkTime 속성이있는 DropDownList에서 선택한 값으로 채워해야합니다.

편집 :은 바인딩 이름과 일치하도록 매개 변수 이름을 변경했습니다.

+0

이것은 드롭 다운 목록의 태그입니다. 'For Each' 아래에있는 두 번째 선언이 MVC로 하여금 모델에 대한 바인딩을 인식하지 못하게한다고 말하고 있습니까? – ExceptionLimeCat

+0

흥미 롭습니다.모델 바인딩의 VB 버전에 익숙하지 않지만 모델 바인더가 컨트롤러 매개 변수에 값을 매핑 할 수 없기 때문에 Nothing (또는 nulls)을 얻는 이유가 있습니다. 모델이 'currentItem As CompleteList'라는 이름으로 매핑 될 것으로 기대하고 있습니다. – mgnoonan

관련 문제