MVC3 - 将绑定复杂视图中的单个项目发送到ActionResult

时间:2014-01-30 20:17:40

标签: asp.net-mvc-3

感激地收到任何反馈......

我想要做的是在单个表单中生成复杂类型列表,然后一次一个地提交给ActionResult。

我有代码来定义,显示和提交它们(见下文)但是当由于[x]前缀而收到对象时,没有收到任何内容并且值为空。

我已经设法破解了一些东西,但它很难看,并且必须更好!

完整描述

我在视图上显示复杂类型列表。

模型

public class TestItem
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

来自控制器

public ActionResult Index()
{
    ICollection<TestItem> model = new List<TestItem> {
       new TestItem {  ID=1, Name="aaa", Description="aaa desc"},
       new TestItem {  ID=2, Name="bbb", Description="bbb desc"},
       new TestItem {  ID=3, Name="ccc", Description="ccc desc"},
    };
    return View(model);
}

...到视图

<h2>Test</h2>
@Html.EditorFor(m => Model)

使用 EditorTemplate

@model MultiBindTest.Models.TestItem

@using (Html.BeginForm("DoSomething", "Home"))
{
    @Html.HiddenFor(i=>i.ID)
    <ul>
        <li>
            @Html.LabelFor(i => i.Name)
            @Html.EditorFor(i => i.Name)
        </li>
        <li>
            @Html.LabelFor(i => i.Description)
            @Html.EditorFor(i => i.Description)
        </li>
        <li>
            <input type="submit" value="submit" />
        </li>
    </ul>
}

使用多个这样的表单生成html ...

<form action="/Home/DoSomething" method="post">
    <input data-val="true" 
           data-val-number="The field ID must be a number." 
           data-val-required="The ID field is required." 
           name="[2].ID" 
           type="hidden"
           value="3" />    
    <ul>
        <li>
            <label for="">Name</label>
            <input class="text-box single-line" name="[2].Name" type="text" value="ccc" />
        </li>
        <li>
            <label for="">Description</label>
            <input class="text-box single-line" name="[2].Description" type="text" value="ccc desc" />
        </li>
        <li>
            <input type="submit" value="submit" />
        </li>
    </ul>
</form>; 

注意 [2]。字段上的前缀。这在所有实例上都重复,因此第一个表单字段是预先确定的[0]。第二种形式是[1]。等

将个别表单提交给以下ActionResult

public ActionResult DoSomething(TestItem model)
{

    System.Diagnostics.Debug.Print(model.Name);

    return View("Index");
}

模型项始终为空。

黑客是......

    public ActionResult DoSomething2(FormCollection form)
    {
        string id = form.GetKey(1).Split('.').First();
        string x = form[string.Format("{0}.ID", id)].ToString();
        return View("Home");
    }

哪个是讨厌的,我真的不想使用它!

修改

我也试过

public ActionResult DoSomething(TestItem[] model)
{

    System.Diagnostics.Debug.Print(model.Name);

    return View("Index");
}

哪个有效...如果我点击页面上的第一个表单,但如果我点击任何后续表单,模型为空。也许我正走在正确的道路上......

当我点击它的第一个项目时(通过firebug)

[0].Description aaa desc
[0].ID          1
[0].Name        aaa

并且控制器接收

testItem                  {MultiBindTest.Models.TestItem[1]}
testItem[0]               {MultiBindTest.Models.TestItem}
testItem[0].Description   "aaa desc"
testItem[0].ID            1
testItem[0].Name          "aaa"

如果我点击表单上的第二页,则发布

[1].Description bbb desc
[1].ID          2
[1].Name        bbb

并收到

testItem    null

2 个答案:

答案 0 :(得分:1)

您可以将TestItem的编辑器称为部分

<h2>
    Test</h2>
@foreach (var item in Model)
{
    @Html.Partial("EditorTemplates/TestItem", item)
}

希望这会有所帮助。

答案 1 :(得分:0)

如果前缀是问题,那么使用这样的东西就不容易了:

public ActionResult DoSomething([Bind.Prefix("MyPrefix")]TestItem model)
{

    System.Diagnostics.Debug.Print(model.Name);

    return View("Index");
}

有关如何定义自己的前缀的指示,因为您使用的是自定义编辑器模板,请检查http://thatextramile.be/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/

这是关于部分观点,但我认为它提供了适用于您的案例的信息。