在回发后重新绑定ASP MVC2 VS2010 Beta2中的文本框列表

时间:2010-02-02 13:17:40

标签: asp.net-mvc data-binding view viewstate c#-4.0

所以......我有一个问题。我敢肯定几乎所有尝试过MVC的人都拥有它。然而,我一直没有成功地使用谷歌搜索解决方案或为自己考虑解决方案。

问题是这样的:我有一个文本框列表,我想一次编辑,我也想在我的列表中添加新项目。但是,第一次回发后文本绑定失败。

所以我举了一个小例子来说明问题:

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

    <fieldset>
        <legend>Fields</legend>
        <% foreach(string s in Model) { %>
        <p>
          <%= Html.TextBox("list",s) %>
        </p>
        <% } %>
        <p>
            <%= Html.TextBox("newstr") %>
        </p>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>

    <% } %>

控制器代码:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Edit()
    {
        return View(new List<string>() { "aa", "bb", "cc" });
    }

    // Remove empty strings and add the new one
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(List<string> list, string newstr)
    {
        List<string> res = list.Where(s => !string.IsNullOrWhiteSpace(s)).ToList();

        if (!string.IsNullOrWhiteSpace(newstr))
            res.Add(newstr);

        return View(res);
    }

所以,在第一次GET时,我返回3个字符串aa,bb和cc,并获得3个带有文本的文本框,以及用于新字符串的空文本框,如下所示:

aa
bb
cc
Empty.

现在,如果我清除bb字符串并在空文本框中添加“dd”,我会在newstr中获得“aa”,“”,“cc”和“dd”的返回列表。这将返回一个新的“aa”,“cc”,“dd”列表,这是我希望在复选框中看到的内容。相反,我得到:

aa
aa
aa
dd (expected empty)

所以..有一些根本我没有得到:)为什么它会忽略我的新数据模型并使用一些旧的而不是全部?

我认为它来自asp.net的某种viewstate剩余,所以我该如何关闭它?我真的想要广告中的无状态网页。

2 个答案:

答案 0 :(得分:0)

有趣的问题。 Html.TextBox()中似乎存在问题。我调试了你的代码,正如你所看到的,View中的Model确实包含了正确的List。 (顺便说一句,我在Visual Studio 2008中对此进行了测试)。

转换

<%=Html.TextBox("list", s) %>

到标准

<input id="list" name="list" value="<%=s %>" /> 

它的工作方式应该有效。这是一个选择吗?

答案 1 :(得分:0)

如果你查看你的html源代码,你会发现这与viewstate无关。在帖子后填充输入时,框架将首先搜索已发布的值并根据该值填充您的输入。这就是为什么你的最后一个输入会得到“dd”。你在其余输入中获得“aa”的原因是它们都具有相同的名称。你的帖子看起来像这样:

list =“aa”,list =“”,list =“cc”

因此,当您使用名称“list”呈现输入时,框架将搜索该帖子并获取匹配的第一个值。每次都是“aa”。这就是为什么你在所有输入中得到“aa”的原因。您不应该有多个<input type="text" />具有相同的名称。使用唯一名称,您将使用循环输入解决问题。

我不确定是否有办法让<%=Html.TextBox()%>无法查看已发布的数据。但您可以随时将其更改为常规<input type="text" name="newstr" />,这样就可以了。