【问题标题】:How to read partial view model from parent view post action method?如何从父视图发布操作方法中读取部分视图模型?
【发布时间】:2015-05-06 10:04:17
【问题描述】:

我的项目中有一个场景,如下所示。

创建具有两个视图的 Person。一种是父视图包含人名,另一种是部分视图包含地址信息。

如果我点击父视图中的提交按钮,我需要读取在地址部分视图中输入的数据并将其传递给 PersonViewModel 对象以用于 POST 操作方法。

我无法通过 POST Action 方法访问 AddressViewModel,得到空值。任何人都可以帮助我如何解决此问题。

提前致谢。

请在下面找到示例代码。

视图模型:

 public class PersonViewModel
 {
    public string FirstName{get;set;}
    public string LastName{get;set;}
    public AddressViewModel Address{get;set;}
 }

 public class AddressViewModel
 {
    public class Address1{get;set;}
    public class Address2{get;set;}
 }

人员控制器

 public ActionResult POST(PersonViewModel model)
 {
    Person person=new Person();
    person.FirstName=model.FirstName;
    person.LastName=model.LastName;

    if(model.Address!=null)
    {
         person.Address1=model.Address.Address1;
    }

    return View("Confirmation");
 }

地址控制器:

public ActionResult Address()
{
    return View();
}

个人视图:

@model POC.ViewModels.PersonViewModel

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
            </div>
        </div>
        <div>
        @{Html.RenderPartial("~/Views/Shared/_Address.cshtml");}
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>

}

地址部分视图:

@model POC.ViewModels.AddressViewModel
<div class="form-horizontal">

    <div class="form-group">
        @Html.LabelFor(model => model.Address1, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Address1, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Address1, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Address2, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Address2, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Address2, "", new { @class = "text-danger" })
        </div>
    </div>
</div>

【问题讨论】:

  • 在视图中显示你是如何调用局部的。
  • 您需要显示视图。如果它没有绑定它是因为你的视图代码是错误的!
  • @Hanu 风景在哪里?
  • @StephenMuecke,我添加了视图。请查看并建议我。
  • 您的部分正在使用name="Address1" 生成控件,但您的模型不包含名称为Address1 的属性(只有一个名为Address 的属性,它是一个包含名为@987654329 的属性的复杂对象@. 我将很快发布一个答案,提供 2 个选项来解决这个问题。

标签: asp.net asp.net-mvc


【解决方案1】:

您的部分正在使用name="Address1"name="Address2" 生成控件,但您的模型不包含名称为Address1Address2 的属性(只有一个名为Address 的属性,它是一个包含属性@ 的复杂对象987654327@ 和 Address2。为了绑定到您的模型,名称属性需要是 name="Address.Address1"name="Address.Address2"

解决此问题的最佳方法是通过将其重命名为 AddressViewModel.cshtml 并将其放置在 Views\Shared\EditorTemplates 文件夹(或 Views\YourControllerName\EditorTemplates 文件夹中,然后在主视图中使用

@Html.EditorFor(m => m.Address)

使用部分的另一种方法是使用附加的ViewData 将前缀传递给部分

@Html.Partial("Address", Model.Address, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Address" }})

This answer 还包括一个 html 辅助扩展方法的示例,该方法使添加前缀更容易

【讨论】:

    【解决方案2】:

    您需要在视图中创建一个表单。像这样的:

    @using (Html.BeginForm("POST")){
      @Html.EditorFor(m => m.FirstName)
      @Html.EditorFor(m => m.Address.Address1)
      <input type="submit"/>  
    }
    

    创建请求的是提交表单的行为。使用帮助程序创建输入字段也很重要,或者如果您想自己创建它们,请使用正确的名称创建它们,例如:

    &lt;input type="text" name="Address.Address1"/&gt;

    注意 name 属性的值,这是 EditorFor 将生成的值。此名称很重要,以便模型绑定器将在 PersonViewModel.Address.Address1 中设置 Address1 值

    如果您使用部分视图呈现地址,则必须确保输入的名称设置正确。这不是一个好主意,因为要使所有这些工作,PersonViewModel 中的 AddressViewModel 属性名称必须是 Address,如果您将其名称更改为,例如 MyAddress,您需要将输入的名称更新为 MyAddress.Address1 等。

    【讨论】:

    • 感谢您的建议。正如您在视图中建议的那样,不需要添加局部视图,但是如果我们想从局部视图中读取数据并将其分配给父视图模型,我该怎么做。请提出建议。
    • @Hanu,有 3 次您被要求在问题中包含该视图,以便我们为您提供正确答案。不要让我们猜测你做错了什么!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多