MVC2 TextBoxFor提交后值不更新?

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

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

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

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

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

这是要复制的代码:

/Views/Demo/Index.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>    Demo   
Foo: x.Foo)%>
Bar: x.Bar) %>
PoopSmith: x.PoopSmith) %>

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); } } 

这是奇怪的输出:

奇怪的http://sofzh.miximages.com/c%23/308cwvb.png

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

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

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

忘掉“大多数人”,用“每个人”取而代之。

ASP.NET MVC:使用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

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

如何更新文本框值

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

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

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

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

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