ASP.NET MVC 3中如何编辑IEnumerable<T>?

17

给定以下类型

public class SomeValue
{
    public int Id { get; set; }
    public int Value { get; set; }
}

public class SomeModel
{
    public string SomeProp1 { get; set; }
    public string SomeProp2 { get; set; }
    public IEnumerable<SomeValue> MyData { get; set; }
}

我想为类型 SomeModel 创建一个编辑表单,该表单将包含常规文本字段 SomeProp1SomeProp2,然后包含一个表格,其中每个 SomeModel.MyData 集合中的 SomeValue 都有一个文本字段。

如何实现?值如何绑定回模型?

我目前有一个表单,显示了每个值的文本字段,但它们都具有相同的名称和相同的 ID。这显然不是有效的 HTML,并且会阻止 MVC 将值映射回来。

2个回答

14
您可以使用编辑模板来完成此操作。这样,框架将处理一切(包括正确命名输入字段和在后续操作中正确绑定值)。
控制器:
public class HomeController : Controller
{
    public ActionResult Index()
    {
        // In the GET action populate your model somehow
        // and render the form so that the user can edit it
        var model = new SomeModel
        {
            SomeProp1 = "prop1",
            SomeProp2 = "prop1",
            MyData = new[] 
            {
                new SomeValue { Id = 1, Value = 123 },
                new SomeValue { Id = 2, Value = 456 },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(SomeModel model)
    {
        // Here the model will be properly bound
        // with the values that the user modified
        // in the form so you could perform some action
        return View(model);
    }
}

View (~/Views/Home/Index.aspx):

<% using (Html.BeginForm()) { %>

    Prop1: <%= Html.TextBoxFor(x => x.SomeProp1) %><br/>
    Prop2: <%= Html.TextBoxFor(x => x.SomeProp2) %><br/>
    <%= Html.EditorFor(x => x.MyData) %><br/>
    <input type="submit" value="OK" />
<% } %>

最后是编辑模板(~/Views/Home/EditorTemplates/SomeValue.ascx),它将自动为MyData集合中的每个元素调用:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyApp.Models.SomeValue>" %>
<div>
    <%= Html.TextBoxFor(x => x.Id) %>
    <%= Html.TextBoxFor(x => x.Value) %>
</div>

嘿,我想现在不用发帖了,因为你的回答已经更好了 :) 我不知道你可以这么容易地绑定列表。谢谢。 - Buildstarted
2
对于MVC3来说,使用Razor不是更好吗? - arame3333

1

IList 实现了 IEnumerable,所以你可以像这样修改你的模型:

public class SomeModel {
    public string SomeProp1 { get; set; }
    public string SomeProp2 { get; set; }
    public IList<SomeValue> MyData { get; set; }
}

您可以使用 IModelBinder 接口为您的特定模型创建绑定器。有几种方法可以实现。您可以为该模型创建一个 EditorFor cshtml,它将循环遍历您的 SomeValue 列表并输出适当的 ID 等内容。然后,在您的 ModelBinder 实现中,您将读取您的 ID 并适当地进行绑定。稍后我可以发布一个可工作的示例。


当表单提交时,ViewEngine会负责将数据绑定回集合中的正确元素吗? - Greg B
你知道什么真的很奇怪...我本来发誓这个问题问了另外一件事情...我想我同时在阅读两个问题并回答了错误的一个...我要改变我的答案。 - Buildstarted

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接