Подтвердить что ты не робот

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

А вот странный вывод:

Bizarre

4b9b3361

Ответ 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, и я обнаружил, что я ударил по стене целый день. После того, как я подумал всю ночь, я думаю, что нашел причину. Причина - настойчивость. Он запоминает все значения, введенные в браузере. Однако я считаю, что это нарушает принцип привязки. Если мне разрешено передать параметр модели в представление, представление должно привязать этот параметр, взяв все, что я передаю в текущем состоянии модели.