C# 在控制器上绑定视图数据
我有当前的ViewModel:C# 在控制器上绑定视图数据,c#,asp.net,asp.net-mvc,razor,C#,Asp.net,Asp.net Mvc,Razor,我有当前的ViewModel: public class ServiceSheetViewModel { public List<ServiceSheetQuestionViewModel> questions { get; set; } public List<VehicleAction> actions { get; set; } } 在控制器上: [HttpPost] public ActionResult CreateServiceSheet([
public class ServiceSheetViewModel
{
public List<ServiceSheetQuestionViewModel> questions { get; set; }
public List<VehicleAction> actions { get; set; }
}
在控制器上:
[HttpPost]
public ActionResult CreateServiceSheet([Bind(Include = "questions,actions")] ServiceSheetViewModel model, int vehicleId, int serviceSheetId)
当我提交表格时,它没有约束力
在post信息中,它说它发送了一个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" />
}
这是车辆操作的编辑器模板
:
@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)
编辑2-以下是有关post数据的信息:
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
首先删除[Bind]
属性(使用视图模型时不需要该属性)
从简单的开始,将@foreach(Model.actions中的var todo){…}
循环的操作
替换为
@Html.EditorFor(m => m.actions)
并确保您的EditorTemplate
位于/Views/Shared/EditorTemplates
(或/Views/youControllerName/EditorTemplates
)文件夹中,并命名为VehicleAction.cshtml
。EditorFor()
方法接受IEnumerable
,并将为集合中的每个项目正确生成html
questions
未绑定的问题在于DefaultModelBinder
(默认情况下)要求集合索引器从零开始,并且是连续的。@foreach(Model.questions.Where…
和@foreach(Model.questions.Where…
中的var项)中的逻辑,特别是if(Model.questions[i].Question.IsGroup){…}else{…}
块表示您没有生成连续的索引器(您的请求显示它们的顺序是[1]
,[0]
,[3]
,[2]
)
解决此问题的一种方法是为集合索引器包含一个隐藏输入,以覆盖DefaultModelBinder
的默认行为,但这意味着您不能使用EditorTemplate
,您将需要for
循环来生成控件。请参阅中的第一个代码段以获取必要的hi示例dden输入
但是,这种逻辑不属于视图,特别是因为您已经在使用视图模型。您的ServiceSheetQuestionViewModel
应该有两个集合属性,例如ServiceSheetQuestionViewModel
public List<ServiceSheetQuestionViewModel> GroupedQuestions { get; set; }
public List<ServiceSheetQuestionViewModel> UngroupedQuestions { get; set; }
处理视图中当前使用的if/else
块
您没有提供足够的信息来理解foreach
循环中的逻辑在做什么,但您似乎有一个基于ParentQuestion
属性的层次结构,这意味着您的视图模型也应该有一个层次结构,即Question
需要包含一个列出子问题
属性,以便您可以使用嵌套的
编辑器或模板
或进行循环
作为旁注,呈现所有这些隐藏的输入是不必要的,也是不好的做法(恶意用户很容易发回坏数据,而您只会降低性能)。只需为问题ID
属性生成一个隐藏输入,然后在提交时,根据ID从数据库中获取原始信息,并根据视图模型仅更新您在视图中编辑的属性。显示视图(您在其中生成表单控件的循环和编辑器将使用ServiceSheetQuestionViewModel
和VehicleAction
)@StephenMuecke I为视图添加了完整的HTML。
@Html.EditorFor(m => m.actions)
public List<ServiceSheetQuestionViewModel> GroupedQuestions { get; set; }
public List<ServiceSheetQuestionViewModel> UngroupedQuestions { get; set; }
@Html.EditorFor(m => m.GroupedQuestions)
@Html.EditorFor(m => m.UngroupedQuestions)