12

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

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

奇怪的是,在视图中,模型似乎包含更新的值,但是当我执行 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>

演示模型.cs

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

演示控制器.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);
        }
}

这是奇怪的输出:

离奇

4

5 回答 5

14

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

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

我已经看到一些人解决了这个问题(我认为是通过写信给 ModelState),但我的选择始终是如果他们不帮助我,就不要使用默认助手。对于隐藏字段尤其如此:大多数人在为隐藏字段设置值时会感到困惑,但真正使用的值来自帖子。至少每隔一天就有一个关于它的问题:-)

忘记“大多数人”,用“所有人”代替。

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

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

如何更新文本框值

于 2010-05-27T22:11:58.780 回答
6

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

于 2010-09-03T06:24:11.893 回答
3

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

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

于 2011-03-30T20:12:24.287 回答
1

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

于 2011-03-31T13:33:52.503 回答
0

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

于 2011-03-31T13:27:16.967 回答