2016-12-05 26 views
1

綁定查看數據我目前的視圖模型:控制器上

public class ServiceSheetViewModel 
{ 
    public List<ServiceSheetQuestionViewModel> questions { get; set; } 
    public List<VehicleAction> actions { get; set; } 
} 

而且,在視圖上,我產生了以下內容:

@Html.EditorFor(modelItem => Model.questions[j], "ServiceSheetQuestionViewModel"); 
@Html.EditorFor(m => Model.actions[i], "VehicleAction"); 

在控制器:

[HttpPost] 
public ActionResult CreateServiceSheet([Bind(Include = "questions,actions")] ServiceSheetViewModel model, int vehicleId, int serviceSheetId) 

當我提交表單時,它沒有約束力。

關於發佈信息,它說它發送一個列表ServiceSheetQuestionViewModel和列表VehicleActions

如何正確地使表單綁定正確?

編輯1 - 查看代碼

@model SupervisedSolutions.Models.ViewModels.ServiceSheetViewModel 
.... 
@using (Html.BeginForm("CreateServiceSheet", "PerformService", Model)) 
{ 
    .... 
    @foreach (var rootItem in Model.questions.Where(x => x.Question.IsGroup || (!x.Question.IsGroup && (x.Question.ParentQuestion == null || x.Question.ParentQuestion.ID == 0))).ToList()) 
    { 
     var i = Model.questions.IndexOf(rootItem); 
     if (Model.questions[i].Question.IsGroup) 
     { 
      @Html.HiddenFor(m => Model.questions[i].Question.ID) 
      @Html.HiddenFor(m => Model.questions[i].Question.Title) 
      @Html.HiddenFor(m => Model.questions[i].Question.Description) 
      @Html.HiddenFor(m => Model.questions[i].Question.IsGroup) 
      @Html.HiddenFor(m => Model.questions[i].Question.OrderIndex) 
      @Html.HiddenFor(m => Model.questions[i].Question.ParentQuestion.ID) 
      @Html.HiddenFor(m => Model.questions[i].Question.ParentQuestion.setDeleted) 
      @Html.HiddenFor(m => Model.questions[i].Question.ParentQuestion.Title) 
      @Html.HiddenFor(m => Model.questions[i].Question.ParentQuestion.Created) 
      <h1>@Model.questions[i].Question.Title</h1> 
      <p>@Model.questions[i].Question.Description</p> 
      .... 
      @foreach (var item in Model.questions.Where(x => !x.Question.IsGroup && (x.Question.ParentQuestion != null && x.Question.ParentQuestion.ID == Model.questions[i].Question.ID)).ToList()) 
      { 
       var j = Model.questions.IndexOf(item); 
       @Html.EditorFor(modelItem => Model.questions[j], "ServiceSheetQuestionViewModel"); 
      } 
     } 
     else 
     { 
      @Html.EditorFor(modelItem => Model.questions[i], "ServiceSheetQuestionViewModel"); 
     } 
    } 
    @foreach (var todo in Model.actions) 
    { 
     var i = Model.actions.IndexOf(todo); 
     @Html.EditorFor(m => Model.actions[i], "VehicleAction"); 
    } 
    <input type="submit" value="Start Run" class="btn btn-info" /> 
} 

這是EditorTemplateServiceSheetQuestionsViewModel

@model SupervisedSolutions.Models.ViewModels.ServiceSheetQuestionViewModel 
.... 
@Html.HiddenFor(m => m.Question.ID) 
@Html.HiddenFor(m => m.Question.Title) 
@Html.HiddenFor(m => m.Question.Description) 
@Html.HiddenFor(m => m.Question.IsGroup) 
@Html.HiddenFor(m => m.Question.OrderIndex) 
@Html.HiddenFor(m => m.Question.ParentQuestion.ID) 
@Html.HiddenFor(m => m.Question.ParentQuestion.setDeleted) 
@Html.HiddenFor(m => m.Question.ParentQuestion.Title) 
@Html.HiddenFor(m => m.Question.ParentQuestion.Created) 
<b>@Html.DisplayFor(m => m.Question.Title)</b> 
<label> 
    @Html.RadioButtonFor(m => m.isFault, "Fault")Fault 
</label> 
<label> 
    @Html.RadioButtonFor(m => m.isFault, "NoFault")No Fault 
</label> 
@Html.LabelFor(model => model.FaultDescription) 
@Html.TextAreaFor(model => model.FaultDescription) 
@Html.ValidationMessageFor(model => model.FaultDescription) 
@Html.ValidationMessageFor(m => m.isFault) 

這是EditorTemplateVehicle Action

@model SupervisedSolutions.Models.VehicleAction 

@Html.LabelFor(model => model.Description) 
@Html.TextAreaFor(model => model.Description) 
@Html.ValidationMessageFor(model => model.Description) 

@Html.LabelFor(model => model.Priority) 
@Html.TextAreaFor(model => model.Priority) 
@Html.ValidationMessageFor(model => model.Description) 

@Html.LabelFor(m => m.DueDate> 
@Html.EditorFor(model => model.DueDate) 
@Html.ValidationMessageFor(m => m.DueDate) 

EDIT 2 - 這裏是有關發佈數據的信息:

vehicleId:50 
serviceSheetId:1 
ID:0 
questions[1].Question.ID:3 
questions[1].Question.Title:Testing 
questions[1].Question.Description:AASDASD 
questions[1].Question.IsGroup:True 
questions[1].Question.OrderIndex:1 
questions[1].Question.ParentQuestion.ID: 
questions[1].Question.ParentQuestion.setDeleted: 
questions[1].Question.ParentQuestion.Title: 
questions[1].Question.ParentQuestion.Created: 
questions[0].Question.ID:1 
questions[0].Question.Title:Test Question 
questions[0].Question.Description:Habba 
questions[0].Question.IsGroup:False 
questions[0].Question.OrderIndex:0 
questions[0].Question.ParentQuestion.ID:3 
questions[0].Question.ParentQuestion.setDeleted:False 
questions[0].Question.ParentQuestion.Title:Testing 
questions[0].Question.ParentQuestion.Created:28/11/2016 7:35:12 PM 
questions[0].isFault:NoFault 
questions[0].FaultDescription:Teste 
questions[3].Question.ID:5 
questions[3].Question.Title:Group 2 
questions[3].Question.Description:Groupin 2 
questions[3].Question.IsGroup:True 
questions[3].Question.OrderIndex:0 
questions[3].Question.ParentQuestion.ID: 
questions[3].Question.ParentQuestion.setDeleted: 
questions[3].Question.ParentQuestion.Title: 
questions[3].Question.ParentQuestion.Created: 
questions[2].Question.ID:4 
questions[2].Question.Title:Test Question 23 
questions[2].Question.Description:TEEEE 
questions[2].Question.IsGroup:False 
questions[2].Question.OrderIndex:0 
questions[2].Question.ParentQuestion.ID:5 
questions[2].Question.ParentQuestion.setDeleted:False 
questions[2].Question.ParentQuestion.Title:Group 2 
questions[2].Question.ParentQuestion.Created:1/12/2016 4:19:49 PM 
questions[2].isFault:NoFault 
questions[2].FaultDescription:Teste 
actions[0].Description:Erro2 
actions[0].Priority:1 
actions[0].DueDate:2010-01-01 
+0

向您展示視圖(您生成表單控件的循環以及您用於「ServiceSheetQuestionViewModel」和「VehicleAction」的EditorTemplates) –

+0

@StephenMuecke我爲視圖添加了完整的HTML。 –

回答

1

首先刪除您[Bind]屬性(使用視圖模型時,該屬性不要求)。

爲了用簡單的一個開始,只有

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

更換@foreach (var todo in Model.actions){ ... }環路actions並確保您的EditorTemplate位於/Views/Shared/EditorTemplates(或/Views/youControllerName/EditorTemplates)文件夾,並命名爲VehicleAction.cshtmlEditorFor()方法接受IEnumerable<T>並將正確地爲集合中的每個項目生成html。

questions未綁定的問題是DefaultModelBinder(默認情況下)要求集合索引器從零開始並且是連續的。您在@foreach (var rootItem in Model.questions.Where.....@foreach (var item in Model.questions.Where...中的邏輯,尤其是if (Model.questions[i].Question.IsGroup){ ... } else { ... }塊意味着您沒有生成連續索引器(您的請求顯示它們的順序爲[1],[0],[3],, [2])。要解決這個

的一種方法是,以包括收集索引覆蓋DefaultModelBinder的默認行爲隱藏的輸入,但是這意味着你不能使用EditorTemplate,您需要for循環生成控件。請參閱this answer中的第一個代碼片段以獲取必要隱藏輸入的示例。

但是,這種邏輯不屬於視圖,特別是因爲您已經在使用視圖模型。你ServiceSheetViewModel應該有2個集合屬性爲ServiceSheetQuestionViewModel,說

public List<ServiceSheetQuestionViewModel> GroupedQuestions { get; set; } 
public List<ServiceSheetQuestionViewModel> UngroupedQuestions { get; set; } 

,你的基礎上的IsGroup的值時,控制器填充這些集合。然後在視圖中,您可以簡單地使用

@Html.EditorFor(m => m.GroupedQuestions) 
@Html.EditorFor(m => m.UngroupedQuestions) 

處理您目前正在使用在視圖中if/else塊。

您尚未提供足夠的信息來了解foreach循環正在執行的邏輯,但看起來您擁有基於您的ParentQuestion屬性的分層結構,這意味着您的視圖模型還應具有分層結構,即a Question需要包含List<Question> SubQuestions屬性,以便您可以使用nestedEditorTemplatesfor循環。作爲一個側面說明,渲染所有這些隱藏的輸入是不必要的和不好的做法(惡意用戶可以輕鬆地回發不良數據,並且只會降低性能)。只需爲問題ID屬性生成一個隱藏輸入,並在提交時根據ID從數據庫中獲取原始數據,並僅根據視圖模型更新您在視圖中編輯的屬性。