2013-05-17 2 views
2

그래,이 사람이 나를 도와 줄 수 있기를 바랍니다. (미리 감사드립니다.) MVC4를 사용하고 있습니다.MVC PartialView의 여러 폼이 나열된 첫 번째 항목을 제외한 모든 항목에 대해 널 (null)을 반환합니다.

내 ContractsModel에는 (다른 것들 중에서) ContractModel 목록이 들어 있습니다. 내 부분보기에서, 나는 목록을 작성하여 각각에 대한 양식을 만듭니다. 여태까지는 그런대로 잘됐다. 문제는 포스트 백에 있습니다. 첫 번째 양식은 항상 정상적으로 게시됩니다. 그러나 다른 (2, 3, 4 등)은 항상 null을 반환합니다.

디버깅 도구를 사용하여 확인한 다음 렌더링 된 컨트롤의 이름이 적절하게 지정되었는지 확인했습니다.

<select name="Contracts[0].OrganizationId" id="Contracts_0__OrganizationId"> 
<select name="Contracts[1].OrganizationId" id="Contracts_1__OrganizationId"> 
<select name="Contracts[2].OrganizationId" id="Contracts_2__OrganizationId"> 

는 또한 클라이언트가 실제로 서버에 데이터를 반환하지만, 어떤 이유로 내 ActionResult 기대되는 모델에 다시 부착하기 할 것 같지 않음을 확인했습니다. 어떤 아이디어?

간결함을 위해 코드를 최소화했습니다. 여기

내 모델입니다 :

다음
public class ContractsModel 
{ 
    public ContractsModel() 
    { 
     this.Contracts = new List<ContractModel>(); 

     this.OrganizationList = new List<SelectListItem>(); 
     this.ContractNumList = new List<SelectListItem>(); 
    } 

    public string ParentProjectId { get; set; } 
    // etc, etc ..... 

    public List<ContractModel> Contracts { get; set; } 

    public List<SelectListItem> OrganizationList { get; set; } 
    public List<SelectListItem> ContractNumList { get; set; } 
} 


public class ContractModel 
{ 
    public string OrganizationId { get; set; } 
    public string Organization { get; set; } 
    public string ContractNumId { get; set; } 
    public string ContractNum { get; set; } 
} 

은 언뜻 내 부분보기

@model Manager.Models.ContractsModel 

@for (int i = 0; i < Model.Contracts.Count(); i++) 
{ 
    var divId = "divContractsModelItem_" + (i + 1); 
    var saveButtonId = "btnContractsEditSave_" + (i + 1); 


    <div id = "@divId"> 

     @using (Html.BeginForm("_ContractsEdit", "Projects", FormMethod.Post)) 
     {  
      <fieldset> 
       <legend>General:</legend> 

       <div> 
        <label>Contracting Organization:</label> 
        @Html.DropDownListFor(model => model.Contracts[i].OrganizationId, new SelectList(Model.OrganizationList, "value", "text", Model.Contracts[i].OrganizationId)) 
       </div> 

       <div> 
        <label>Contract Number:</label> 
        @Html.DropDownListFor(model => model.Contracts[i].ContractNumId, new SelectList(Model.ContractNumList, "value", "text", Model.Contracts[i].ContractNumId)) 
       </div> 

       <div> 
        <button id="@saveButtonId" type="submit">Save</button> 
       </div> 

      </fieldset> 
     } 
    </div> 

} 
+0

내 생각 엔 누락 된 색인 문제가 발생했다 ([이 블로그] (http://www.hanselman.com/) 참조). 블로그/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx))를 사용하여 여러 양식을 만들었습니다. 가장 좋은 방법은이 경우 문제를 해결하는 것입니다. –

+0

(하나의 양식으로 이동하여 어떤 제출 버튼이 눌려 졌는지 그리고 따라서 어떤 계약 정보가 저장되었는지 결정하는 것 이외에) –

+0

그랬습니다! 감사합니다 –

답변

1

제 의견이 도움이 되셨으므로 전 대답으로 풀어 냈습니다.

모델 바인딩 문제는 배열 인덱스를 건너 뛰는 것을 허용하지 않는다는 것입니다. 배열 인덱스를 건너 뛰면 바인딩이 중지됩니다. 귀하의 페이지에는 각 계약서마다 하나씩 여러 양식이 있습니다. 따라서 두 번째 및 후속 양식은 인덱스 0에서 시작하지 않습니다. 인덱스 1에서 시작한 다음 인덱스 2에서 시작합니다. 따라서 모델 바인딩이 즉시 실패하고 컨트롤러에 null 객체가 전달됩니다.

단순한 솔루션은 모델 바인딩이 계약 오브젝트의 모든 색인에 액세스 할 수 있도록 단일 양식으로 이동 한 다음 제어기에서 여분의 코드를 사용하여 제출 된 제출 단추를 판별하는 것입니다.

서버에 게시되는 불필요한 데이터의 양이 줄어들 기 때문에 multiple forms and submit buttons is better from an HTTP point of view을 갖는 것이 가장 좋은 해결책이라고 확신하지는 않습니다. 그러나 최상의 것은 원수이며, 하나의 형식이 작동하는 경우 ...

0

이며,이 사이의 분리처럼 보이는 여기 내 컨트롤러 조치

[HttpPost] 
public ActionResult _ContractsEdit(ContractsModel model) 
{ 

    if (ModelState.IsValid) { 
     //blah, blah, blah.... 
    } 

    return PartialView("Index", ProjectModel); 
} 

입니다 각 폼이 나타내는 것과 포스트 컨트롤러 메소드가 기대하는 것. 컨트롤러 인스턴스가 전체 계약 모델을 기대하면서 각 폼 인스턴스가 하나의 계약을 나타내는 것처럼 보입니다. 아마도 계약을 맺기 위해 컨트롤러 방법을 변경해보십시오.

+0

이미 시도 ... 내 컨트롤러는 여전히 null을받습니다. 흥미로운 점은 첫 번째 형식이 모델을 올바르게 반환한다는 점입니다. 그 형식은 null을 반환합니다. –

+0

일종의 의미가 있습니다. 이제 생각해 봅시다. 런타임에서 계약서 [2]를 게시 중입니다.계약 [1]과 계약 [0]은 어디에 있습니까? 첫 번째 문제는 아무런 문제가 없습니다. 런타임에서 무엇을해야할지 파악할 수 있습니다. 많은 것을 렌더링하고 많은 것을 담는 컨테이너에 한 가지를 게시하는 사이에 상속 된 불일치가 있습니다. –

+0

제이슨의 제안은 아마도 가장 쉬운 방법 일 것입니다. –