2010-05-27 3 views
12

Это действительно странное поведение, и я создал демо-код, чтобы попытаться выяснить, что происходит.MVC2 TextBoxFor значение не обновляется после отправки?

В основном есть два действия и один вид. Первое действие отправляет пустую модель в представление, действие раздела получает модель, изменяет ее содержимое и отправляет обратно в тот же вид.

Похоже, что модель, по-видимому, имеет в ней обновленные значения, но когда я делаю Html.TextBoxFor (x => x.PropertyNameHere), она отображает текстовое поле с неизменным значением в нем.

lol ... Я заранее извиняюсь за юмористический туалет, но он не дает деньу стать слишком скучным. ;)

Кто-нибудь знает, что здесь происходит? Почему вывод 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); 
     } 
} 

И h прежде чем это причудливое выход:

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

ответ

14

По умолчанию Html помощник пытаются повторно отобразить данные, размещенные на них. Сначала они используют значение из опубликованных данных, и если нет доступных данных, они берут данные из Модели.

Это не то, что вы хотите, но, тем не менее, наиболее распространенное использование. Вы можете отобразить некоторые данные в поля формы после получения запроса на получение. Вы отправляете сообщение об обновлении. Если у вас есть ошибки, вы хотите повторно отобразить форму с введенными вами значениями.

Я видел, как некоторые люди обошли это (я думаю, написав на ModelState), но мой выбор всегда заключался в том, чтобы не использовать помощники по умолчанию, если они мне не помогают. Особенно это касается скрытых полей: большинство людей путают, когда устанавливают значение в скрытое поле, но значение, которое реально используется, - это сообщение. По крайней мере, есть вопрос каждый день об этом на SO :-)

Забудьте «Большинство людей» и замените его «Все».

ASP.NET MVC: Hidden field value does not get rendered using 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 О, я нашел еще одну с сегодняшнего дня (Вы не одиноки):

How to update textbox value

+0

+1 LOL! Ваши навыки поиска превосходят мои! Это имеет смысл, спасибо за ответ. –

6

Do ModelState.Очистить(); в вашем контроллере, чтобы это не произошло. Проверить MSDN для этого.

3

Я бы избегал ModelState.Clear() или ModelState.Remove(), если вам абсолютно не нужно. Обычно, если вы видите это поведение, это связано с тем, что: а) вы не следуете шаблону Post-Redirect-Get и должны быть, или b) если это не подходит, вы должны не использовать метод TextBox HtmlHelper, поскольку он в основном разработанный, чтобы помочь с проверкой и т. д., следуя шаблону PRG.

Я уверен, что есть исключения (например, пользовательский интерфейс в стиле мастера может немного походить на это), но я бы принял это как подход по умолчанию.

0

У меня такая же проблема с VS 2010, и я обнаружил, что я ударил по стене целый день. После того, как я подумал всю ночь, я думаю, что нашел причину. Причина - настойчивость. Он запоминает все значения, введенные в браузере. Однако я считаю, что это нарушает принцип привязки. Если мне разрешено передать параметр модели в представление, представление должно привязать этот параметр, взяв все, что я передаю в текущем состоянии модели.

1

Решение должно использовать либо ModelState.Remove ("[Свойство свойства режима]"), прежде чем ему будет присвоено новое значение с помощью Контроллера. Или на странице просмотра измените Html.TextBoxFor() на Html.TextBox() для конкретного свойства модели.