提交MVC 5视图时,缺少部分视图中的数据

时间:2015-09-03 10:30:53

标签: c# asp.net asp.net-mvc asp.net-mvc-5 asp.net-mvc-partialview

这个问题已被问到,但没有一个可以解决我的问题。 缺少问题或部分视图中的空数据未与主视图数据一起提交(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属性不是。 我哪里出错?

非常感谢你。

5 个答案:

答案 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" />

你的解决方案很少:

  1. 手动插入输入名称:

     @Html.HiddenFor(x => x.Street, new { Name = "Address.Street" })
    
  2. 使用Html.EditorFor()

  3. 覆盖Html.Partial()

  4. 中解析的名称

    第一个解决方案的缺点是你正在硬编码属性名称,这是不理想的。我建议使用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")
}