2011-02-03 17 views
8

En mi opinión tengoHtml.TextBoxFor no muestra valor actualizado en acción POST

 <%:Html.LabelFor(model => model.IPAddress)%> 

    <div class="editor-field"> 
     <%:Html.TextBoxFor(model => model.IPAddress)%> 
     <%:Html.ValidationMessageFor(model => model.IPAddress)%> 
    </div> 

En mi controlador (método POST), tengo unas pocas cosas

[HttpPost] 
public ActionResult Manipulation(MyModel model){ 
    //I change modele here 
    if(somthing) 
    model.IPAddress="100.100.100.100"; 
    return View(model); 
} 

Por lo tanto, mi pregunta es: Cuando cambio el modelo, TextBoxFor no cambia su valor. TextBoxPara obtener su valor cuando llegue del método get a la publicación, y luego no puedo cambiar el valor de TextBoxFor. Depuro, y mi modelo tiene un nuevo valor, pero TextBoxFor no muestra un nuevo valor.

¿Me puede ayudar?

Respuesta

11

Probar:

ModelState.Clear(); 
return View(model); 

Si no resultará! devolver un resultado JSON y luego actualizar mediante javascript

+1

'ModelState.Clear();' funciona a la perfección. ¿Puedes explicar porque? – cashmere

+0

Usted me salvó el día. Pero una explicación sería agradable :) –

1

En lugar de utilizar enlace de modelos, identificación sugieren el uso de una llamada tryupdate.

[HttpPost] 
public ActionResult Manipulation(FormCollection formCollection) 
{ 
    MyModel model = new MyModel(); 

    if(TryUpdate(Model)) 
    { 
     enter code here 
    } 

    if(somthing) 
    model.IPAddress="100.100.100.100"; 
    return View(model); 
} 

Mira mi respuesta a otra publicación para la estructura general que uso. Nunca me ha fallado antes y creo que cubre todas las bases al actualizar los modelos de la entrada del usuario.

asp.net mvc controller post best practices

+0

Si es un tipo anidado, por ejemplo, modelo de vista que contiene un modelo, puede ser necesaria una sobrecarga de prefijo para el modelo tryupdate. – Manatherin

0

Sr. Grok tenía un sitio similar problema this. Ya había encontrado el ModelState.Clear() solución, pero faltaba una explicación de por qué funcionaba. La respuesta mejor clasificada en el sitio vinculado propuso que el comportamiento del helper html es un error, para el cual ModelState.Clear() es una solución alternativa. Sin embargo, bradwils en this sitio dice que el comportamiento es por diseño, y da la siguiente explicación:

La razón por la que utilizamos el valor publicado por los editores en lugar del valor del modelo es que el modelo puede no ser capaz de contener la valor que el usuario tipeó. Imagine en su editor "int" que el usuario ha escrito "perro". Desea mostrar un mensaje de error que dice "perro no es válido" y deje "perro" en el campo del editor. Sin embargo, su modelo es un int: no hay forma de que pueda almacenar "dog". Así que mantenemos el valor anterior.

Si no desea que los viejos valores en el editor, limpiar el modelo de estados. Ahí es donde se guarda el viejo valor y se extrae de los ayudantes de HTML.

A pesar del hecho de que es por diseño, este comportamiento es muy inesperado para el desarrollador, y es desafortunado que se requiera la interacción con el modelo de estado para una necesidad de programación común.

Por otra parte, la limpieza de toda la ModelState puede causar problemas inesperados en otras áreas (creo que con respecto a la validación de campos del modelo no relacionadas). Así que muchas gracias a Peter Gluck (responder en un comentario dentro de la página del Sr. Grok) para proponer la más limitada ModelState.Remove (“llave”), y Toby J para el desarrollo de un método más conveniente que funciona cuando no está seguro cuál debería ser la clave si la propiedad del modelo está anidada. También me gusta el método de Toby porque no depende de una cadena como entrada.

Ese método, con pequeños cambios, sigue:

/// <summary> 
/// Removes the ModelState entry corresponding to the specified property on the model. Call this when changing 
/// Model values on the server after a postback, to prevent ModelState entries from taking precedence. 
/// </summary> 
/// <param name="model">The viewmodel that was passed in from a view, and which will be returned to a view</param> 
/// <param name="propertyFetcher">A lambda expression that selects a property from the viewmodel in which to clear the ModelState information</param> 
/// <remarks> 
/// Code from Tobi J at https://stackoverflow.com/questions/1775170/asp-net-mvc-modelstate-clear 
/// Also see comments by Peter Gluck, Metro Smurf and Proviste 
/// Finally, see Bradwils http://forums.asp.net/p/1527149/3687407.aspx. 
/// </remarks> 
public static void RemoveStateFor<TModel, TProperty>(
    this ModelStateDictionary modelState, 
    TModel model, 
    Expression<Func<TModel, TProperty>> propertyFetcher 
) { 
    var key = ExpressionHelper.GetExpressionText(propertyFetcher); 

    modelState.Remove(key); 
} 
0

Aquí hay otro trabajo en torno a que he encontrado. En lugar de

@Html.TextBoxFor(m=>m.PropertyName) 

hacer esto

@{ 
var myModel = Model; 
} 
@Html.TextBoxFor(m=>myModel.PropertyName) 

Esto podría ser útil si no desea anular el comportamiento por defecto para cada entrada.

Cuestiones relacionadas