这个问题已被问到,但没有一个可以解决我的问题。 缺少问题或部分视图中的空数据未与主视图数据一起提交(POST)。
我有一个名为 _Address.cshtml 的打字部分视图,我将其包含在另一个名为Site.cshtml的视图中。
键入的网站视图绑定到名为 SiteEditModel.cs 的视图模型
public class SiteEditModel
{
...properties
public AddressEditModel Address {get;set;}
public SiteEditModel()
{
Address = new AddressEditModel();
}
}
网站视图的格式为:
@model Insight.Pos.Web.Models.SiteEditModel
...
@using ( Html.BeginForm( "Edit", "Site", FormMethod.Post ) )
{
@Html.HiddenFor( m => m.SiteId )
...
@Html.Partial( "~/Views/Shared/Address.cshtml", this.Model.Address )
...
@Html.SaveChangesButton()
}
部分地址视图只是绑定到地址模型的一堆@Html ...调用。
@model Insight.Pos.Web.Models.AddressEditModel
@{
Layout = null;
}
<div>
@Html.HiddenFor(...)
@Html.HiddenFor(...)
@Html.HiddenFor(...)
@hmtl.LabelFor(...)
</div>
在控制器操作Edit中,我可以看到SiteEditModel已正确填充,该模型的Address属性不是。 我哪里出错?
非常感谢你。
答案 0 :(得分:1)
解决这个问题的关键是命名partialviews input-elements。渲染部分不知道它是更大的一部分。
我已经举例说明了如何使用相同的局部视图来解决这个问题:
public static class HtmlHelperExtensions
{
public static MvcHtmlString PartialWithPrefix(this HtmlHelper html, string partialViewName, object model, string prefix)
{
var viewData = new ViewDataDictionary(html.ViewData)
{
TemplateInfo = new TemplateInfo
{
HtmlFieldPrefix = prefix
}
};
return html.Partial(partialViewName, model, viewData);
}
}
并在视图中使用此扩展程序:
@using (Html.BeginForm("Edit", "Site", FormMethod.Post))
{
@Html.HiddenFor(m => m.SiteId)
@Html.PartialWithPrefix("_Adress", this.Model.Address, "Address")
<input type="submit" />
}
你当然可以通过表达和反思使这更加花哨,但那是另一个问题; - )
答案 1 :(得分:1)
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
@Html.Partial("~/Views/Shared/_Address.cshtml", Model.Address, new ViewDataDictionary
{
TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Address" }
})
答案 2 :(得分:0)
您的SiteEditModel
Address
媒体资源未标记为public
,请将其更改为:
public AddressEditModel Address {get;set;}
我也会更改您的部分使用SiteEditModel
代替:
@model Insight.Pos.Web.Models.SiteEditModel
@{
Layout = null;
}
<div>
@Html.HiddenFor(m => m.Address.FooProperty)
...
</div>
这意味着您的属性最终会被正确命名,以便模型绑定器选择它们。
使用上面的示例,它将是Name"=Address.FooProperty"
。
答案 3 :(得分:0)
我记得很清楚,问题是Html.Partial
没有正确填充输入名称。你应该有类似的东西:
<input id="Address.Street" name="Address.Street" />
但我假设你有以下HTML:
<input id="Street" name="Street" />
你的解决方案很少:
手动插入输入名称:
@Html.HiddenFor(x => x.Street, new { Name = "Address.Street" })
使用Html.EditorFor()
覆盖Html.Partial()
第一个解决方案的缺点是你正在硬编码属性名称,这是不理想的。我建议使用Html.EditorFor()
或Html.DisplayFor()
助手,因为它们会正确填充输入名称。
答案 4 :(得分:0)
如果在部分视图中填充子模型,则模型绑定器无法正确绑定子模型。考虑使用编辑器模板,而不是出于这个原因而实现的。
将AddressEditModel.cshtml
文件放在\Views\Shared\EditorTemplates\
文件夹中,在主视图中使用如下:
@using ( Html.BeginForm( "Edit", "Site", FormMethod.Post ) )
{
// because model type name same as template name MVC automatically picks our template
@Html.EditorFor(model=>model.Address)
// or if names do not match set template name explicitly
@Html.EditorFor(model=>model.Address,"NameOfTemplate")
}