Ben*_*esh 12 c# asp.net-mvc model-binding asp.net-mvc-2
这是一个非常奇怪的行为,我已经设置了一些演示代码来试图弄清楚发生了什么.
基本上有两个动作和一个视图.第一个操作将一个空模型发送到视图,该部分操作接收模型,更改其内容并将其发送回同一视图.
在视图中,模型似乎具有更新的值,但是当我执行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>
Run Code Online (Sandbox Code Playgroud)
DemoModel.cs
namespace TestWeb {
public class DemoModel {
public string Foo { get; set; }
public int Bar { get; set; }
public string PoopSmith { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是奇怪的输出:
Mat*_*s F 14
默认Html帮助程序尝试重新显示发布给它们的数据.他们首先使用发布数据中的值,如果没有可用的发布数据,他们将从模型中获取数据.
这显然不是你想要的,但仍然是最常见的用法:在收到get请求后在formfields中显示一些数据.您发布到更新操作.如果您有错误,则要重新显示表单,并输入您仍然可用的值.
我已经看到有些人绕过这个(我想通过写入ModelState),但我的选择总是不使用默认助手,如果他们不帮助我.这对于隐藏字段尤其如此:大多数人在将值设置为隐藏字段时会感到困惑,但实际使用的值来自帖子.至少在SO上每隔一天都有一个问题:-)
忘掉"大多数人",用"每个人"取而代之.
ASP.NET MVC:使用HtmlHelper.Hidden不会呈现隐藏字段值
http://blog.johnwest.com/post/ASPNET-MVC-Hidden-Form-Field-Bug.aspx
更新 哦,我今天发现了另一个(你并不孤单):