我目前正在尝试发布由两个强类型视图组成的表单。这个问题很相似,但没有答案:
MVC 3 Razor Form Post w/ Multiple Strongly Typed Partial Views Not Binding
当我提交表单时,提交给控制器的模型始终为null。我花了几个小时试图让它发挥作用。这似乎应该很简单。我在这里错过了什么吗?我不需要做ajax只需要能够发布到控制器并呈现一个新页面。
由于
这是我的观看代码:
<div>
@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
@Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
@Html.Partial("_ReportOptions", Model.ReportOptions);
@Html.Partial("_TransactionSearchFields", new ViewDataDictionary(viewData) { Model = Model.SearchCriteria });
}
这是控制器中的代码:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TransactionReport(TransactionReportRequest reportRequest)
{
var reportInfo = new List<TransactionReportItem>();
if (ModelState.IsValid)
{
var reportData = _reportDataService.GetReportData(Search.MapToDomainSearchCriteria(reportRequest.SearchCriteria));
if (reportData!=null)
{
reportInfo = reportData.ToList();
}
return View(reportInfo);
}
return View(reportInfo);
}
部分视图本身非常无关紧要,因为他们正在做的就是参与并展示他们的模型。
答案 0 :(得分:51)
部分不是去这里的方式。您正在寻找EditorTemplates,这些是为您想要的。在这种情况下,您的属性将很好地绑定到您的模型(您将提交)。
您的主视图将包含此表单(请注意,您只需使用EditorFor
而不是Partial
;在这种情况下,您可能需要将该viewData参数放在ViewBag中等等) :
@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"}))
{
ViewContext.FormContext.ValidationSummaryId = "valSumId";
@Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } });
@Html.EditorFor(model => model.ReportOptions);
@Html.EditorFor(model = Model.SearchCriteria });
}
现在您只需要将部分文件拖到文件夹~/Shared/EditorTemplates/
并重命名它们以匹配它们作为编辑器模板的模型名称。
在~/Shared/EditorTemplates/
文件夹中,创建一个新的“视图”,例如“SearchCriteria.cshtml”。在里面,将“模型”作为创建编辑器模板的类的类型。示例(示例类具有属性Name
和OtherCriteria
):
@model MyNamespace.SearchCriteria
<ul>
<!-- Note that I also use EditorFor for the properties; this way you can "nest" editor templates or create custom editor templates for system types (like DateTime or String or ...). -->
<li>@Html.LabelFor(m => m.Name): @Html.EditorFor(m => m.Name)</li>
<li>@Html.LabelFor(m => OtherCriteria): @Html.EditorFor(m => m.OtherCriteria</li>
</ul>
关于它们的一些好读物:
答案 1 :(得分:12)
您应该在PartialView的字段中添加前缀。这将正确地绑定数据。
所以相反:
@Html.Partial("_ReportOptions", Model.ReportOptions);
使用:
@Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }})
答案 2 :(得分:10)
我同意@Styxxy和@Tony,编辑模板是更好的解决方案。但是,您的问题是您正在为子视图提供子模型。因此,当局部视图呈现时,它不知道它是较大模型的一部分,并且不会生成正确的名称属性。
如果你坚持使用Partials而不是编辑模板,那么我建议只将模型传递给partials,然后让每个部分执行Model.Whatever.Foo,它将为绑定生成正确的名称属性。
答案 3 :(得分:4)
尝试使用EditorTemplates而不是Partials http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/。
答案 4 :(得分:2)
@Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
)
@Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new
ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "SearchCriteria"
}
})