如何从父视图post action方法中读取局部视图模型?

时间:2015-05-06 10:04:17

标签: asp.net asp.net-mvc

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

使用两个视图创建人物。一个是父视图包含人名,另一个是部分视图包含地址信息。

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

我无法从POST Action方法中获取AddressViewModel,获取空值。任何人都可以帮我解决这个问题。

提前致谢。

请在下面找到示例代码。

的ViewModels:

 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;}
 }

PersonController

 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");
 }

AddressController:

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>

2 个答案:

答案 0 :(得分:1)

您部分使用name="Address1"name="Address2"生成控件,但您的模型不包含名称为Address1Address2的属性(仅限名为{{1的属性)这是一个包含属性AddressAddress1的复杂对象。为了绑定到您的模型,名称属性需要是Address2name="Address.Address1"

解决此问题的最佳方法是将您的部分name="Address.Address2"重命名为EditorTemplate并将其放在AddressViewModel.cshtml文件夹(或Views\Shared\EditorTemplates文件夹中) ,然后在主视图中使用

Views\YourControllerName\EditorTemplates

使用partial的替代方法是使用addititional @Html.EditorFor(m => m.Address)

将前缀传递给partial
ViewData

This answer还包含一个html帮助扩展方法的示例,该方法可以更轻松地添加前缀

答案 1 :(得分:0)

您需要在视图中使用表单。像这样:

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

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

<input type="text" name="Address.Address1"/>

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

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