ASP.NET MVC - 以一种形式处理多个对象

时间:2009-02-12 17:18:10

标签: asp.net-mvc

我有一个我坚持的场景 - 我有一个域对象,它附有一组对象。像这样:

public class Person
{
   public string Name { get; set; }
   public IList<PhoneNumber> PhoneNumbers {get; set; }
   public IList<Address> Addresses { get; set; }
}

客户端想要的UI有一个用于添加和编辑的输入表单。用户可以为每个人输入0到多个电话/地址。如何处理将值集合发布回控制器?

我可以想到几种方法,但它们都显得蛮力而且不是很优雅。是否有处理此类问题的最佳做法?

5 个答案:

答案 0 :(得分:3)

框架支持使用特殊的“表单布局”。 Phil Haack有一篇关于此的文章,check this out

编辑Scott Hanselman(http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx)刚刚发布了此更新。此外,在RC1中,似乎(昨晚遇到了这个问题)索引需要从0开始并且稳步增加(至少如果你对IList“绑定”)

Edit2 Link似乎无法正常工作

答案 1 :(得分:0)

过去我曾使用过这种惯用法。

<input name="Parent[childObjectType][serial_number]" type="textbox" value="" />

所以你的情况呢

<input name="Person[PhoneNumber][1]" type="TextBox" value="555-1212" />
<input name="Person[PhoneNumber][2]" type="TextBox" value="555-555-1212" />

并且您可以增加序列号并在javascript中复制元素以获得多个,并在您的操作中使用formCollection,这将为您提供获取这些元素的方法。

mvc团队的默认设置是使用ModelBinder和此操作的点语法。 然而,这使得jquery和其他javascript框架阻碍。

答案 2 :(得分:0)

我已经开始使用json和jQuery在服务器端使用JSON.NET和JsonFilter将复杂类型发布到控制器操作,它自动获取json对象并将其序列化为等效的C#类型。我发现这是一个非常干净的解决方案,更容易测试。您可以查看此帖子并下载示例代码,以便开始了解如何操作。这很直接。

http://blogger.forgottenskies.com/?p=252

答案 3 :(得分:0)

在上面提到的Hanselman的帖子中,他写道你不需要索引,输入框只有相同的名称,并且有一个数组参数在运行,它可以工作。

答案 4 :(得分:0)

我已经做过几次,并以Phil Haack的帖子为指导。这是我最后一次弄清楚如何使其与“编辑器模板”一起使用。将其发布在这里,希望对以后的其他人(或我,如果我忘记的话)有所帮助。

我的示例在这里使用地址(为简洁起见,仅使用一个属性)。

AddressViewModel.cs

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

AddressViewModels.cs

public class AddressViewModels : List<AddressViewModel>
{
}

PersonViewModel.cs

public class PersonViewModel
{
    public AddressViewModels HomeAddresses { get; set; }
}

AddressViewModel.cshtml(编辑器模板)

@model AddressViewModel

<div>
    @Html.LabelFor(m => m.Address1)
    @Html.TextBoxFor(m => m.Address1)
</div>

AddressViewModels.cshtml(编辑器模板)

@model AddressViewModels
@for (var i = 0; i < Model.Count; i++)
{
    @Html.Hidden("Index", i)
    @Html.EditorFor(m => Model[i])
}

Person.cshtml

@model Person

<h3>Edit Addresses</h3>
@Html.EditorFor(m => m.HomeAddresses)
<button type="submit">Save</button>

渲染的HTML

<input id="HomeAddresses_Index" name="HomeAddresses.Index" type="hidden" value="0">
<label for="HomeAddresses_1__Address1">Address 1</label>
<input id="HomeAddresses_1__Address1" name="HomeAddresses[1].Address1" type="text" value="P.O.Box 123" >
<button type="submit">Save</button>