MVC,从页面中的多个部分视图传回值

时间:2012-03-03 11:12:31

标签: asp.net-mvc collections views

当我尝试从包含相同局部视图两次的页面传回值时,我遇到了问题。 我的课程定义如下:

public class Account : IEntity
{

    public decimal CurrentBalance { get; set; }
    public List<Person> AccountHolders { get; set; }
    //to get round the non-existing enum support in EF4.3 wrap enum to int
    public int StatusValue { get; set; }
    public AccountStatus Status { get { return (AccountStatus)StatusValue; } set { StatusValue = (int) value; } }

    public DateTime AccountOpenDate { get; set; }
    public DateTime AccountCloseDate { get; set; }
    public DateTime AccountSuspensionDate { get; set; }
    }

它有一个人员列表,我对其进行了部分查看(单个人)。

<fieldset>
    <legend>Person</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>
      <div class="editor-label">
        @Html.LabelFor(model => model.Age)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Age)
        @Html.ValidationMessageFor(model => model.Age)
    </div>
</fieldset>

在帐户的“创建”页面中,我包含了我创建的2个部分视图,如下所示。

 <div id="Person1">
        @Html.Partial("_CreateAccountHolder" )
    </div>

     <div id="Person2">
        @Html.Partial("_CreateAccountHolder")
    </div>

当我查看回发的内容时,它包含我在页面的表单值中放置的值(Name和Age作为Person的属性),并且我已按预期方式获得它们的两个: CurrentBalance = 19&安培;状态=封闭&安培; AccountOpenDate = 12%2F12%2F2012&安培;名称=穆斯塔法&安培;年龄= 20&安培;名称=索菲亚&安培;年龄= 20&安培; AccountCloseDate = 12%2F12%2F2012&安培; AccountSuspensionDate = 12%2F12%2F2012

但是当我在我的控制器上查看我的create方法时,我看到AccountHolder列表为null。我试过各种签名...... public ActionResult Create(Account personalaccount,Person [] accountHolders) public ActionResult Create(Account personalaccount,List accountHolders)

如果我只有一个Person的局部视图并让我的控制器像这样,我可以看到Person对象绑定正确。 public ActionResult Create(Account personalaccount,Person accountHolder)

关于我哪里出错的任何想法?

3 个答案:

答案 0 :(得分:2)

如果我正确理解您的场景,一种方法是使用编辑器模板而不是部分视图。我在这里有一点关于它们的文章:

codenodes.wordpress.com - MVC3 Editor Templates

创建编辑器模板:

  • 如果您的解决方案的Web项目中还没有名为“EditorTemplates”的文件夹,请在Views \ Shared文件夹中创建一个文件夹。
  • 添加一个新的局部视图并将其命名为与您渲染的模型相同,在您的情况下为Person,因此您将其称为Person.cshtml(我知道部分视图应该以下划线“_”开头但是对于编辑模板,它需要与模型命名相同。)
  • 将“_CreateAccountHolder”局部视图中的代码粘贴到新的Person.cshtml编辑器模板中。
  • 在您的“创建”页面中呈现您的AccountHolders列表:
<div id="People">
    @Html.EditorFor(x => x.AccountHolders)
</div>

如果您需要在每个人周围设置单独的div,则可以将这些div添加到编辑器模板中。编辑模板的好处在于,即使列表中有多个Person对象,也只需要对模板进行一次调用 - 无需循环或类似的任何内容,因为模板会自动呈现每个Person对象。它还正确命名字段,因此如果你的集合中有2个Person对象,它应该回发这样的东西:

AccountHolders[0].Name
AccountHolders[0].Age
AccountHolders[1].Name
AccountHolders[1].Age

以下是编辑模板的代码:

@model Person

<fieldset>
    <legend>Person</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>
      <div class="editor-label">
        @Html.LabelFor(model => model.Age)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Age)
        @Html.ValidationMessageFor(model => model.Age)
    </div>
</fieldset>

答案 1 :(得分:0)

阅读后我理解了我的问题 [http://stackoverflow.com/questions/653514/asp-net-mvc-model-binding-an-ilist-parameter][1] 放置相同类型的2个部分视图使得视图返回名称和年龄对,在第一对和第二对之间没有任何对应的distingusih。我改变了如下的parial视图,但是不喜欢它......

    <div class="editor-field">
         @Html.TextBox("person[0].Name", "") 
        @Html.ValidationMessageFor(model => model.Name)
    </div>

    <div class="editor-field">
         @Html.TextBox("person[0].Age", "") 
        @Html.ValidationMessageFor(model => model.Age)
    </div>

    <div class="editor-field">
         @Html.TextBox("person[1].Name", "") 
        @Html.ValidationMessageFor(model => model.Name)
    </div>
    <div class="editor-field">
         @Html.TextBox("person[1].Age", "") 
        @Html.ValidationMessageFor(model => model.Age)
    </div>

它现在回发类似下面的东西,我可以在我的控制器中读取IList ..

CurrentBalance = 19&安培;状态=封闭&安培; AccountOpenDate = 12%2F12%2F2012&安培;人%5B0%5D.Name =穆斯塔法&安培;人%5B0%5D.Age = 19&安培;人%5B1%5D.Name =索菲亚&安培;人%5B1%5D.Age = 20&安培; AccountCloseDate = 10%2F10%2F2012&安培; AccountSuspensionDate = 12%2F12%2F2012

答案 2 :(得分:0)

首先,您应该创建具有两个AccountModel实例的CreateAccountModel,类似于:

public class CreateAccountModel
{
    public Account Person1 { get; set; }
    public Account Person2 { get; set; }
}

接下来,当您添加部分视图时,您应该将单个模型传递给它们,例如:

<div id="Person1">
    @Html.Partial("_CreateAccountHolder", Model.Person1)
</div>

 <div id="Person2">
    @Html.Partial("_CreateAccountHolder", Model.Person2)
</div>

现在MVC将自动为所有帐户字段添加前缀PersonX,因此所有字段都是唯一的。

或者,您可以在添加部分视图时手动指定前缀:

{
    var prefixData = new ViewDataDictionary { TemplateInfo = { HtmlFieldPrefix = "Person1" } };
    Html.RenderPartial("_CreateAccountHolder", new ViewDataDictionary(prefixData));
}