我有当前的ViewModel:
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" />
}
这是EditorTemplate
的{{1}}:
ServiceSheetQuestionsViewModel
这是@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)
的{{1}}:
EditorTemplate
编辑2 - 以下是有关帖子数据的信息:
Vehicle Action
答案 0 :(得分:1)
首先删除您的[Bind]
属性(使用视图模型时不需要该属性)。
从简单的方法开始,用{/ 1>替换@foreach (var todo in Model.actions){ ... }
的{{1}}循环
actions
并确保您的@Html.EditorFor(m => m.actions)
位于EditorTemplate
(或/Views/Shared/EditorTemplates
)文件夹中,并命名为/Views/youControllerName/EditorTemplates
。 VehicleAction.cshtml
方法接受EditorFor()
,并会正确生成集合中每个项目的html。
IEnumerable<T>
没有绑定的问题是questions
(默认情况下)要求集合索引器从零开始并且是连续的。 DefaultModelBinder
和@foreach (var rootItem in Model.questions.Where.....
,尤其是@foreach (var item in Model.questions.Where...
块中的逻辑意味着您没有生成连续的索引器(您的请求显示它们的顺序为if (Model.questions[i].Question.IsGroup){ ... } else { ... }
,{{ 1}},[1]
,[0]
)。
解决此问题的一种方法是为集合索引器包含一个隐藏的输入,以覆盖[3]
的默认行为,但这意味着您无法使用[2]
,您将需要{{1 }循环生成控件。请参阅this answer中的第一个代码段,以获取必要隐藏输入的示例。
但是,这种逻辑不属于视图,特别是因为您已经使用了视图模型。您的DefaultModelBinder
应该有EditorTemplate
的2个集合属性,比如说
for
并根据ServiceSheetViewModel
的值在控制器中填充这些集合。然后在视图中,您只需使用
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
Question
或List<Question> SubQuestions
循环。
作为旁注,渲染所有这些隐藏的输入是不必要的和不好的做法(恶意用户可以轻松回发不良数据而你只是降低性能)。只需为问题nested
属性生成隐藏输入,并在提交时,根据ID从数据库中获取原始数据,并仅更新基于视图模型在视图中编辑的属性。