2014-01-17 1 views
3

여기 코드의 양은 유감이지만, 상황을 설명하는 가장 좋은 방법입니다.MVC 4 Ajax.BeginForm POST가 컨트롤러의 모델에 바인딩되지 않습니다.

내 MVC 4 부분보기에이 코드를 준

:

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
    @using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" })) 
    {        
     foreach (var d in Model.DataItemsWithLabels) 
     {          
      @Html.LabelFor(m => d.DataName) 
      @Html.TextBoxFor(m => d.DataValue);    
     } 

     <input type="submit" value="Save" /> 
    } 

다음과 같이 내 컨트롤러 액션은 다음과 같습니다

내 모델에서
public ActionResult TestPost(CmaPartialModel model) 
{   
     return PartialView("Transaction", model); 
} 

나는 개체의 목록을 채 웁니다 몇 가지 코드를 (비어있는 경우에만) :

public List<DataItemWithLabel> DataItemsWithLabels { get; set; }  

    public class DataItemWithLabel 
    { 
     public string DisplayName { get; set; } 

     public string DataName { get; set; } 

     [Required] 
     public string DataValue { get; set; } 
    } 

나는 또한 생각하는 것이 맞습니다 Web.config의 항목 :

여기와 다른 곳에서 더 성공 게시물의 부하를 읽었습니다.

코드는 TestPost 메서드에 게시되지만 모델은 항상 비어 있습니다. 누군가가 왜 이런지 말해 줄 수 있습니까?

답변

6

항상 null 값을 얻는 이유는 모델 바인더가 개체 목록을 바인딩하는 방법을 모르기 때문입니다. 예를 들어 아래를 참조

public class CmaPartialModel 
{ 
    public List<DataItemWithLabel> DataItemsWithLabels { get; set; } 
} 

을 그런 다음보기에서 사용 :

@model CmaPartialModel 

<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> 
@using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" })) 
{ 
    for(var i = 0; i < Model.DataItemsWithLabels.Count; i++) 
    { 
     @Html.LabelFor(m => m.DataItemsWithLabels[i].DataName) 
     @Html.TextBoxFor(m => m.DataItemsWithLabels[i].DataValue) 
    } 
    <input type="submit" value="Save" /> 
} 

마지막으로, 액션 방법은 다음과 같아야합니다

public ActionResult TestPost(CmaPartialModel model) 
{   
     return PartialView("Transaction", model); 
} 

업데이트

또한 수 다음과 같이보기에서 foreach을 사용하십시오 :

foreach (var item in Model.DataItemsWithLabels.Select((value, i) => new { i, value })) 
{ 
    @Html.LabelFor(m => m.DataItemsWithLabels[@item.i].DataName) 
    @Html.TextBoxFor(m => m.DataItemsWithLabels[@item.i].DataValue); 
} 
+0

감사합니다 Lin - 내 ViewModel과 똑같은 목록을 이미 가지고 있습니다. 저는 CmaPartialModel이라고 부릅니다. 솔루션은 거의 작동하지만 foreach가 아니라 for 루프가 유일한 차이점은 무엇입니까 - 왜 foreach가 문제가되거나 뭔가를 놓친 것입니까? – davy

+0

안녕하세요 @ 데이터, 모든 DataItemWithLabel 모델을 for 루프 또는 foreach 루프로 사용하는 문제가 아니라 두 모델 중 하나를 사용할 수 있습니다. 문제는 foreach를 사용하여 모든 항목을 루프 할 때 모델 바인더가 데이터를 바인딩하는 방법을 모르는 경우입니다. 따라서 모든 항목을 표시하기 위해 색인과 같은 것을 작성해야하며, 모델 바인더는 모든 항목 목록의 데이터를 바인드합니다. 나는 이것을하기 위해 foreach를 사용하는 방법에 대한 나의 대답을 업데이트했다. – Lin

0

당신은 당신이 당신의 컨트롤러에 DataItemWithLabel 모델의 컬렉션을 전달하는 때문에

public ActionResult TestPost(IEnumerable<DataItemWithLabel> model) 
{   
     return PartialView("Transaction", model); 
} 

을 다음과 같이 포스트 방법을 수정해야합니다.

+0

감사합니다. 내 DataItemWithLabel이 CmaPartialModel 모델 내에 있더라도 null이 반환됩니다. – davy

1
I think below code will help you. 

보기

@model MvcApplication1.Models.CmaPartialModel 
@{ 
ViewBag.Title = "Index"; 
} 
<h2>Index</h2> 
@using (Ajax.BeginForm("TestPost", new AjaxOptions { HttpMethod = "Post" })) 
{ 
    if (Model != null) 
    { 
    foreach (var d in Model.DataItemsWithLabels) 
    {          
     @Html.LabelFor(m => d.DataName) 
     @Html.TextBoxFor(m => d.DataValue); 
    } 
    } 
    <input type="submit" value="Save" /> 
} 

모델

public class CmaPartialModel 
{ 
    public List<DataItemWithLabel> DataItemsWithLabels { get; set; } 

    public class DataItemWithLabel 
    { 
     public string DisplayName { get; set; } 

     public string DataName { get; set; } 

     public string DataValue { get; set; } 
    } 
} 

컨트롤러

public ActionResult Index() 
    { 
     return View(); 
    } 
    public ActionResult TestPost(CmaPartialModel model) 
    { 
     List<CmaPartialModel.DataItemWithLabel> parts = new  List<CmaPartialModel.DataItemWithLabel>(); 
     parts.Add(new CmaPartialModel.DataItemWithLabel() {DisplayName = "abc",DataName = "cbv",DataValue = "343"}); 
     parts.Add(new CmaPartialModel.DataItemWithLabel() { DisplayName = "sfda", DataName = "xzfdsf", DataValue = "234" }); 
     model.DataItemsWithLabels = parts; 
     return PartialView("Index", model); 
    } 
관련 문제