MVC2 TextBoxFor值不更新后提交?

时间:2023-02-02 00:20:23

This is a really strange behavior, and I've set up some demo code to try to figure out what's going on.

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

Basically have a a two actions and a single view. The first action sends an empty model to the view, the section action recieves the model, alters its contents and sends it back to the same view.

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

The wierdness is, in the view, the Model seems to have the updated values in it, but when I do an Html.TextBoxFor(x => x.PropertyNameHere) it renders a textbox with the unaltered value in it.

在视图中,这个模型似乎有更新的值,但是当我做Html的时候。TextBoxFor(x => x. propertynamehere)它呈现一个包含未修改值的文本框。

lol... I apologize in advance for the toilet humor, but it keeps the day from getting too boring. ;)

哈哈我提前为卫生间里的幽默道歉,但它使一天不至于变得太无聊。,)

Does anyone have any idea what's going on here? Why is the output of TextBoxFor putting the old value in the value attribute?

有人知道这是怎么回事吗?为什么将旧值放入值属性的textboxoutput ?

Here's the code to replicate:

下面是复制的代码:

/Views/Demo/Index.aspx

/ /演示/ 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

DemoModel.cs

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

DemoController.cs

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

And here's the bizarre output:

这里是奇怪的输出:

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

奇怪的http://i47.tinypic.com/308cwvb.png

5 个解决方案

#1


14  

Default Html helper try to redisplay the data that is posted to them. They first use the value from posted data and if no posted data is available they take the data from the Model.

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

This is not what you want obviously, but still the most common usage: You display some data in formfields after receiving a get request. You post to an Update action. If you have errors you want to redisplay the form with the values you entered still available.

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

I have seen some people getting around this (I think by writing to ModelState), but my choice was always to not use the default helpers if they dont help me. Thats especially true for hidden fields: Most people get confused when they set a value to a hidden field but the value that is realy used is from the post. At least there is a question every other day about it on SO :-)

我曾见过一些人回避这个问题(我认为是通过写信给ModelState),但我的选择是,如果他们不帮助我,就永远不要使用默认的helper函数。对于隐藏字段尤其如此:大多数人在为隐藏字段设置值时感到困惑,但实际使用的值来自post。至少每隔一天就会有一个关于它的问题

Forget the "Most people" and replace it with "Everybody".

忘掉“大多数人”,换成“所有人”。

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

ASP。NET MVC:隐藏字段值不会被html .Hidden渲染

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

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

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

UPDATE Oh I found another one from today (You are not alone):

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

How to update textbox value

如何更新文本框值

#2


6  

Do ModelState.Clear(); in your controller to prevent this happening. Check MSDN for that.

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

#3


3  

I'd avoid ModelState.Clear() or ModelState.Remove() unless you absolutely have to. Generally if you see this behaviour it is because a) you're not following the Post-Redirect-Get pattern and should be, or b) if that isn't appropriate you should consider not using the HtmlHelper's TextBox method, as it is mainly designed to help with validation etc when following a PRG pattern.

我将避免ModelState.Clear()或ModelState.Remove(),除非您必须这样做。通常,如果您看到这种行为,是因为a)您没有遵循后重定向获取模式,应该是;b)如果不合适,您应该考虑不使用HtmlHelper的TextBox方法,因为它主要是在遵循PRG模式时帮助进行验证等。

I'm sure there are exceptions (for example a Wizard-style UI can end up a bit like this), but I'd take that as the default approach.

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

#4


1  

The solution is to use either ModelState.Remove("[Mode's Property Name]") before it is assigned new value with the Controller. Or on the view page, change Html.TextBoxFor() to Html.TextBox() for the particular model property.

解决方案是使用任何一个ModelState。在向控制器分配新值之前,删除(“[模式的属性名]”)。或者在视图页面上,为特定的模型属性将Html.TextBoxFor()更改为Html.TextBox()。

#5


0  

I got the same problem with VS 2010 and I found I hit the wall the whole day. After I thought about the whole night, I think I found the reason. The reason is the persistence. It only remembers whatever value entered on the browser. However, I think this violates the binding principle. If I am allowed to pass a model parameter to the view, the view should bind that parameter by taking whatever I pass in the model's current state.

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

#1


14  

Default Html helper try to redisplay the data that is posted to them. They first use the value from posted data and if no posted data is available they take the data from the Model.

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

This is not what you want obviously, but still the most common usage: You display some data in formfields after receiving a get request. You post to an Update action. If you have errors you want to redisplay the form with the values you entered still available.

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

I have seen some people getting around this (I think by writing to ModelState), but my choice was always to not use the default helpers if they dont help me. Thats especially true for hidden fields: Most people get confused when they set a value to a hidden field but the value that is realy used is from the post. At least there is a question every other day about it on SO :-)

我曾见过一些人回避这个问题(我认为是通过写信给ModelState),但我的选择是,如果他们不帮助我,就永远不要使用默认的helper函数。对于隐藏字段尤其如此:大多数人在为隐藏字段设置值时感到困惑,但实际使用的值来自post。至少每隔一天就会有一个关于它的问题

Forget the "Most people" and replace it with "Everybody".

忘掉“大多数人”,换成“所有人”。

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

ASP。NET MVC:隐藏字段值不会被html .Hidden渲染

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

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

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

UPDATE Oh I found another one from today (You are not alone):

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

How to update textbox value

如何更新文本框值

#2


6  

Do ModelState.Clear(); in your controller to prevent this happening. Check MSDN for that.

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

#3


3  

I'd avoid ModelState.Clear() or ModelState.Remove() unless you absolutely have to. Generally if you see this behaviour it is because a) you're not following the Post-Redirect-Get pattern and should be, or b) if that isn't appropriate you should consider not using the HtmlHelper's TextBox method, as it is mainly designed to help with validation etc when following a PRG pattern.

我将避免ModelState.Clear()或ModelState.Remove(),除非您必须这样做。通常,如果您看到这种行为,是因为a)您没有遵循后重定向获取模式,应该是;b)如果不合适,您应该考虑不使用HtmlHelper的TextBox方法,因为它主要是在遵循PRG模式时帮助进行验证等。

I'm sure there are exceptions (for example a Wizard-style UI can end up a bit like this), but I'd take that as the default approach.

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

#4


1  

The solution is to use either ModelState.Remove("[Mode's Property Name]") before it is assigned new value with the Controller. Or on the view page, change Html.TextBoxFor() to Html.TextBox() for the particular model property.

解决方案是使用任何一个ModelState。在向控制器分配新值之前,删除(“[模式的属性名]”)。或者在视图页面上,为特定的模型属性将Html.TextBoxFor()更改为Html.TextBox()。

#5


0  

I got the same problem with VS 2010 and I found I hit the wall the whole day. After I thought about the whole night, I think I found the reason. The reason is the persistence. It only remembers whatever value entered on the browser. However, I think this violates the binding principle. If I am allowed to pass a model parameter to the view, the view should bind that parameter by taking whatever I pass in the model's current state.

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