MVC2 TextBoxFor значение не обновляется после отправки?
Это действительно странное поведение, и я настроил демонстрационный код, чтобы попытаться выяснить, что происходит.
В основном есть два действия и одно представление. Первое действие отправляет пустую модель в представление, действие section получает модель, изменяет ее содержимое и отправляет обратно в то же представление.
Странность, на взгляд, в модели, похоже, есть обновленные значения, но когда я делаю 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);
}
}
А вот странный вывод:
Ответы
Ответ 1
Помощник по умолчанию Html попытается повторно отобразить данные, которые отправляются на них.
Сначала они используют значение из опубликованных данных, и если нет опубликованных данных, они берут данные из Модели.
Это не то, что вы хотите, но, тем не менее, наиболее часто используемое: вы получаете некоторые данные в поля формы после получения запроса на получение. Вы отправляете сообщение об обновлении. Если у вас есть ошибки, вы хотите повторно отобразить форму с введенными вами значениями.
Я видел, как некоторые люди обошли это (я думаю, написав на ModelState), но мой выбор всегда заключался в том, чтобы не использовать помощников по умолчанию, если они мне не помогают. Особенно это касается скрытых полей: большинство людей путают, когда устанавливают значение в скрытое поле, но значение, которое реально используется, - это сообщение. По крайней мере, каждый день возникает вопрос об этом на 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
UPDATE
О, я нашел еще одну сегодня (вы не одиноки):
Как обновить значение текстового поля
Ответ 2
Сделайте ModelState.Clear(); в вашем контроллере, чтобы это не произошло.
Проверьте MSDN для этого.
Ответ 3
Я бы избегал ModelState.Clear() или ModelState.Remove(), если вам абсолютно не нужно. Как правило, если вы видите это поведение, это связано с тем, что: а) вы не следуете шаблону Post-Redirect-Get и должны быть, или b) если это не подходит, вам следует не использовать метод HtmlHelper TextBox, поскольку он в основном разработанный, чтобы помочь с проверкой и т.д., следуя шаблону PRG.
Я уверен, что есть исключения (например, пользовательский интерфейс в стиле Wizard может немного походить на это), но я бы принял это как подход по умолчанию.
Ответ 4
Решение заключается в использовании либо ModelState.Remove( "[Свойство свойства режима]" ), прежде чем ему будет присвоено новое значение с помощью контроллера. Или на странице просмотра измените Html.TextBoxFor() на Html.TextBox() для конкретного свойства модели.
Ответ 5
У меня такая же проблема с VS 2010, и я обнаружил, что я ударил по стене целый день. После того, как я подумал всю ночь, я думаю, что нашел причину. Причина - настойчивость. Он запоминает все значения, введенные в браузере. Однако я считаю, что это нарушает принцип привязки. Если мне разрешено передать параметр модели в представление, представление должно привязать этот параметр, взяв все, что я передаю в текущем состоянии модели.