2017-03-08 80 views
1

你好,Mighty Stackoverflowers,ASP.NET MVC 4.5地圖部分視圖到窗體上的主視圖提交

我目前正在研究ASP.NET MVC 4.5應用程序。 當我提交創建表單時,我需要將輸入值從我的分部視圖映射到主視圖模型。

在我看來「Create.cshtml」我稱之爲局部視圖「_SwotPart.cshtml」。我通過我的視圖模型的一部分,以局部視圖,類似這樣的:

Create.cshtml:

@model MyCoolApp.BLL.Models.MainVm 

@foreach (var swot in Model.Swots) 
{ 
     <tr> 
      @foreach (var swotPart in swot.SwotParts) 
      { 
       @Html.Partial("~/Views/Shared/_SwotPart.cshtml", swotPart) 
      } 
     </tr> 
} 

我的部分觀點如下所示,_SwotPartial。 cshtml:

<td class="form-group"> 
    @Html.TextAreaFor(model => model.Label, htmlAttributes: new { Name = nameField, ID = nameField, @class = "form-control", placeholder = Model.SwotTypeId.GetLabel() }) 
</td> 

無論如何,當我提交表單時,部分視圖中的值永遠不會到達控制器。

你有任何想法如何正確映射這個嗎?

謝謝!

回答

0

問題在於輸入名稱,它將以您當前嘗試實現此目的的方式生成。剃刀需要整個列表的上下文,或者至少需要項目在其中的位置,以便生成正確的輸入名稱。換句話說,解決您的問題(一個警告)最簡單的方法是:

@for (var i = 0; i < Model.Swots.Count(); i++) 
{ 
    ... 

    @for (var j = 0; j < Model.Swots[i].SwotParts.Count(); j++) 
    { 
     if (Model.Swots[i].SwotParts[j].SwotTypeId == SwotType.InternalHelpful || Model.Swots[i].SwotParts[j].SwotTypeId == SwotType.InternalHarmful) 
     { 
      @Html.Partial("~/Views/Shared/_SwotPart.cshtml", Model.Swots[i].SwotParts[j]) 
     } 
    } 

    ... 

然後,局部有正確的情況下繼續努力,你的輸入將被命名爲喜歡Swots[0].SwotParts[0].Label,該模型綁定器會能夠工作。

但是,這裏需要注意的是,你將這個列表分成兩個循環。這還沒有起作用,因爲您正在有效地解決模型中項目位置的總體上下文。爲了解決這個問題,你應該在你的模型,這是更好的,反正拆你的列表,你可以從您的視圖中刪除此業務邏輯:

public class SwotVm 
{ 
    ... 

    public List<SwotPartVm> InternalSwotParts { get; set; } 
    public List<SwotPartVm> ExternalSwotParts { get; set; } 
} 

然後,您可以簡單地在每個列表迭代單獨和值自然會回到適當的清單。

鑑於您正在使用partial來渲染特定類類型的字段,不過,您最好通過創建編輯器模板來提供服務。如果你只是你的部分代碼移到視圖:Views\Shared\EditorTemplates\SwotPartVm.cshtml,然後在你的主視圖,你可以這樣做:

@for (var i = 0; i < Model.Swots.Count(); i++) 
{ 
    ... 

    <tr> 
     <th class="swot-heading">Internal</th> 
     @Html.EditorFor(m => m.Swots[i].InternalSwotParts) 
    </tr> 
    <tr> 
     <th class="swot-heading">External</th> 
     @Html.EditorFor(m => m.Swots[i].ExternalSwotParts) 
    </tr> 
} 

這是顯而易見的清潔,並且你可以通過添加SwotVm.cshtml進一步延伸這個概念編輯模板,讓你只需更換代碼連這一點:

@Html.EditorFor(m => m.Swots) 

注:在您的SwotVm.cshtml編輯模板,你將只包含一個SwotVm的代碼。換句話說,不包括for聲明。

+0

感謝克里斯對這個偉大而詳細的解釋! – TimHorton

0

爲了讓您的應用程序解析發佈的值並正確地綁定到您的視圖模型。發佈表單數據的名稱需要類似。

SWOTS [X1] .swotParts [X2] .label

其中X 1是一個數字範圍從0並且至多爲每個SWOT。 其中,對於swot中的每個swot部分,x2是從0到上的數字。

現在,當您發佈時,表單數據名稱僅爲標籤

相反的:

@Html.TextAreaFor(model => model.Label, htmlAttributes: new { Name = nameField, ID = nameField, @class = "form-control", placeholder = Model.SwotTypeId.GetLabel() }) 

嘗試:

<textarea name="swots[x1].swotParts[x2].label" class="form-control" placeholder="@Model.SwotTypeId.GetLabel()" >@Model.Label</textarea> 

不要忘記更換X1和X2與多家。

您可以在這裏閱讀更多關於模型綁定到集合的信息。

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

+0

感謝您的幫助和好主意! – TimHorton