MVC2 TextBoxFor值提交后没有更新?

时间:2010-05-27 20:31:21

标签: c# asp.net-mvc asp.net-mvc-2 model-binding

这是一个非常奇怪的行为,我已经设置了一些演示代码来试图弄清楚发生了什么。

基本上有两个动作和一个视图。第一个动作向视图发送一个空模型,该部分动作接收模型,改变其内容并将其发送回同一视图。

在视图中,Wiledness似乎有更新的值,但是当我执行Html.TextBoxFor(x => x.PropertyNameHere)时,它会呈现一个文本框中包含未更改的值。

大声笑......我提前为厕所幽默道歉,但它让这一天变得无聊。 ;)

有谁知道这里发生了什么?为什么TextBoxFor的输出将旧值放在value属性中?

这是要复制的代码:

/Views/Demo/Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<TestWeb.DemoModel>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Demo</title>
</head>
<body>
    <div>
      <%using (Html.BeginForm("DemoSubmit", "Admin", FormMethod.Post)) { %>
        Foo: <%=Html.TextBoxFor(x => x.Foo)%> <%:Model.Foo %><br />
        Bar: <%=Html.TextBoxFor(x => x.Bar) %> <%:Model.Bar %><br />
        PoopSmith: <%=Html.TextBoxFor(x => x.PoopSmith) %> <%:Model.PoopSmith %><br />
        <button type="submit">Submit</button>
      <%} %>
    </div>
</body>
</html>

DemoModel.cs

namespace TestWeb {
    public class DemoModel {
        public string Foo { get; set; }
        public int Bar { get; set; }
        public string PoopSmith { get; set; }
    }
}

DemoController.cs

public class AdminController : Controller {

        public ActionResult Index() {
            var m = new DemoModel();
            return View(m);
        }

        public ActionResult DemoSubmit(DemoModel demo) {
            demo.Foo += "!!!";
            demo.Bar++;
            demo.PoopSmith += " has pooped.";
            return View("Index", demo);
        }
}

这是奇怪的输出:

Bizarre http://i47.tinypic.com/308cwvb.png

5 个答案:

答案 0 :(得分:14)

默认Html帮助程序尝试重新显示发布给它们的数据。 他们首先使用发布数据中的值,如果没有可用的发布数据,他们将从模型中获取数据。

这显然不是你想要的,但仍然是最常见的用法:在收到get请求后,你在formfields中显示一些数据。您发布到更新操作。如果您有错误,则要重新显示表单,并输入您输入的值。

我看到有些人绕过这个(我想通过写入ModelState),但我的选择总是不使用默认助手,如果他们不帮助我。这对于隐藏字段尤其如此:大多数人在将值设置为隐藏字段时会感到困惑,但实际使用的值来自帖子。至少在SO上每隔一天都有一个问题: - )

忘记“大多数人”并将其替换为“每个人”。

ASP.NET MVC: Hidden field value does not get rendered using HtmlHelper.Hidden

http://blog.johnwest.com/post/ASPNET-MVC-Hidden-Form-Field-Bug.aspx

http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx?utm_medium=Twitter&utm_source=Shared

<强>更新 哦,我今天发现了另一个(你并不孤单):

How to update textbox value

答案 1 :(得分:6)

做ModelState.Clear();在你的控制器中,以防止这种情况发生。 检查MSDN

答案 2 :(得分:3)

除非你绝对必须,否则我会避免使用ModelState.Clear()或ModelState.Remove()。通常,如果你看到这种行为,那是因为a)你没有遵循Post-Redirect-Get模式而应该是,或者b)如果这不合适你应该考虑不使用HtmlHelper的TextBox方法,因为它主要是旨在帮助验证等遵循PRG模式。

我确定有例外(例如,向导式UI可能会有点像这样),但我会将其作为默认方法。

答案 3 :(得分:1)

解决方案是在为Controller分配新值之前使用ModelState.Remove(“[Mode的属性名称]”)。或者在视图页面上,将Html.TextBoxFor()更改为特定模型属性的Html.TextBox()。

答案 4 :(得分:0)

我在VS 2010遇到了同样的问题,我发现我整天都在撞墙。在想了整整一夜之后,我想我找到了原因。原因是持久性。它只会记住在浏览器上输入的任何值。但是,我认为这违反了约束原则。如果允许我将模型参数传递给视图,则视图应该通过获取模型当前状态中传递的任何内容来绑定该参数。