当我尝试从包含相同局部视图两次的页面传回值时,我遇到了问题。 我的课程定义如下:
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)
关于我哪里出错的任何想法?
答案 0 :(得分:2)
如果我正确理解您的场景,一种方法是使用编辑器模板而不是部分视图。我在这里有一点关于它们的文章:
codenodes.wordpress.com - MVC3 Editor Templates
创建编辑器模板:
<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));
}