2010-05-27 19 views
12

Este es un comportamiento realmente extraño, y he configurado un código de demostración para tratar de descubrir qué está pasando.MVC2 TextBox ¿El valor no se actualiza después del envío?

Básicamente tiene a dos acciones y una sola vista. La primera acción envía un modelo vacío a la vista, la acción de sección recibe el modelo, altera su contenido y lo envía a la misma vista.

El wierdness es, en la vista, el modelo parece tener los valores actualizados en ella, pero cuando hago un Html.TextBoxFor (x => x.PropertyNameHere) que hace que un cuadro de texto con el valor inalterado en ella.

lol ... Me disculpo de antemano por el humor del inodoro, pero evita que el día se vuelva demasiado aburrido. ;)

¿Alguien tiene alguna idea de lo que está pasando aquí? ¿Por qué la salida de TextBoxFor pone el valor anterior en el atributo de valor?

Aquí está el código para replicar:

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

Y h ERE es la salida extraña:

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

Respuesta

14

HTML predeterminado ayudante de tratar de volver a mostrar los datos que se registró a ellos. Primero usan el valor de los datos publicados y, si no hay datos publicados disponibles, toman los datos del Modelo.

Esto no es lo que desea obviamente, pero sigue siendo el uso más común: muestra algunos datos en formfields después de recibir una solicitud de obtención. Publicas en una acción de Actualización. Si tiene errores, quiere volver a mostrar el formulario con los valores que ingresó aún disponibles.

He visto a algunas personas eludir esto (creo que escribiendo a ModelState), pero mi elección siempre fue no usar los ayudantes predeterminados si no me ayudan. Esto es especialmente cierto para los campos ocultos: la mayoría de las personas se confunden cuando establecen un valor en un campo oculto, pero el valor que realmente se usa proviene de la publicación. Al menos hay una pregunta cada dos días al respecto en SO :-)

Olvídese de la "mayoría de las personas" y reemplácela por "Todos".

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

ACTUALIZACIÓN Oh me encontré con otra a partir de hoy (Usted no está solo):

How to update textbox value

+0

+1 ¡LOL! ¡Tus habilidades de búsqueda son superiores a las mías! Eso tiene sentido, gracias por la respuesta. –

6

Do ModeloEstado.Claro(); en su controlador para evitar que esto suceda. Compruebe MSDN para eso.

3

Evitaría ModelState.Clear() o ModelState.Remove() a menos que sea absolutamente necesario. En general, si ve este comportamiento es porque a) no está siguiendo el patrón de Post-Redirect-Get y debe ser, o b) si no es apropiado, debería considerar no utilizar el método TextBox de HtmlHelper, ya que es principalmente diseñado para ayudar con la validación, etc., cuando se sigue un patrón PRG.

Estoy seguro de que hay excepciones (por ejemplo, una interfaz de usuario estilo Wizard puede terminar un poco así), pero tomaría eso como el enfoque predeterminado.

0

Tuve el mismo problema con VS 2010 y encontré que golpeé la pared todo el día. Después de pensar en toda la noche, creo que encontré la razón. La razón es la persistencia. Solo recuerda cualquier valor ingresado en el navegador. Sin embargo, creo que esto viola el principio vinculante. Si se me permite pasar un parámetro de modelo a la vista, la vista debe vincular ese parámetro tomando todo lo que pase en el estado actual del modelo.

1

La solución es usar ModelState.Remove ("[Nombre de la propiedad del modo]") antes de asignarle un nuevo valor con el Controlador. O en la página de vista, cambie Html.TextBoxFor() a Html.TextBox() para la propiedad de modelo particular.

Cuestiones relacionadas