【问题标题】:When submitting MVC 5 view, data from partial view is missing [duplicate]提交 MVC 5 视图时,部分视图中的数据丢失 [重复]
【发布时间】:2015-09-03 10:30:52
【问题描述】:

有人问过这个问题,但没有人能解决我的问题。 问题是部分视图中的空数据未与主视图数据一起提交 (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 属性未正确填充。 我哪里出错了?

非常感谢。

【问题讨论】:

  • _Address.cshtml 还是 Address.cshtml?

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


【解决方案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" }
})  

【讨论】:

  • 更简单的符号@Daniel Stackenland
【解决方案2】:

解决这个问题的关键是部分视图输入元素的命名。渲染部分不知道它是更大的一部分。

我做了一个简单的例子来说明如何解决这个问题,你可以使用相同的局部视图拥有多个地址:

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" />
}

您当然可以通过表达式和反射使这更花哨,但这是另一个问题 ;-)

【讨论】:

    【解决方案3】:

    您的 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"

    【讨论】:

    • 谢谢。 Address 属性已公开。不是这样。我在我的问题中纠正了这一点。至于在局部视图中使用 SiteEditModel ——这难道不是达到了在那里拥有局部视图的目标吗?还有其他“主”视图也使用 _Address 部分视图,所以我想我不能传入“主视图”EditModel?
    • @John 您的部分将是相同的,只是 model 引用将更改以启用模型绑定器命名。
    【解决方案4】:

    我没记错,问题是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()中解析的名称

    第一个解决方案的缺点是您对属性名称进行了硬编码,这并不理想。我建议使用 Html.EditorFor()Html.DisplayFor() 助手,因为它们会正确填充输入名称。

    【讨论】:

      【解决方案5】:

      如果您在局部视图中填充子模型,模型绑定器无法正确绑定它们。考虑使用编辑器模板,因为这个原因实现了。

      将您的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")
      }     
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多