2011-04-15 6 views
5

que tienen una acción de controlador UpdateCustomer(CustomerDto customer) que devuelve un PartialViewResult con un modelo que es también un CustomerDto:¿Por qué un valor que actualizo en mi modelo dentro de un controlador MVC3 no se representa en el cliente?

[HttpPost] 
public PartialViewResult UpdateCustomer(CustomerDto customer) 
{ 
    CustomerDto updatedCustomer = _customerService.UpdateCustomer(customer); 
    updatedCustomer.Name = "NotThePostedName"; 
    return PartialView("CustomerData", updatedCustomer); 
} 

En mi opinión, tengo la siguiente línea:

@Html.TextBoxFor(model => model.Name) 

Hasta ahora, todo bien . En mi opinión, realizo una publicación asincrónica en este método de acción, el corrector de modelos hace su trabajo y puedo actualizar un cliente en la base de datos. Entonces deseo renderizar el cliente actualizado al cliente. Por ejemplo, me gustaría cambiar el nombre del cliente en mi controlador. Sin embargo, lo que se obtiene es siempre las propiedades del customer publicado, no las propiedades del updatedCustomer.

Decidí incluir el código fuente de MVC3 en mi proyecto para ver qué sucede realmente. Parece ser una característica (¿error?) De MVC3 que siempre toma el valor de ViewData.ModelState en lugar del valor de ViewData.Model.

Esto sucede en las líneas 366-367 de System.Web.Mvc.Html.InputExtensions:

string attemptedValue = 
    (string) htmlHelper.GetModelStateValue(fullName, typeof(string)); 
tagBuilder.MergeAttribute("value", 
    attemptedValue ?? ((useViewData) 
     ? htmlHelper.EvalString(fullName) 
     : valueParameter), isExplicitValue); 

Como se puede ver, attemptedValue proviene de ModelState. Contiene el valor anterior para CustomerDto.Name (el valor que se publicó en la acción del controlador).

Si esta es una función, ¿por qué funciona de esta manera? ¿Y hay una manera de evitarlo? Esperaría que si actualizo mi modelo, se muestre la actualización, no el valor anterior que publiqué.

Respuesta

5

Pues sí, es una característica (ModelState siempre se comprueba antes Modelo real), puede borrar la ModelState, o actualizar sólo el valor que necesita:

ModelState["Name"].Value = updatedCustomer.Name; 
+1

Gracias, esto funciona. ¿Tienes alguna idea de por qué está construida de esta manera? Tengo una vista y le proporciono un modelo, pero las propiedades de ese modelo no se representan. Parece muy contrario a la intuición. –

+0

Creo que la suposición era que si devuelve la misma vista en respuesta a POST, quiere que el usuario vea los datos que ha ingresado. – tpeczek

+1

Para borrar los datos de vista para vistas parciales, simplemente pase "additionalViewData" como un objeto vacío. esto anulará los datos de vista para la vista parcial. Los datos de vista se heredan de la vista principal a menos que se anule de otra manera. Esto puede permitirle evitar establecer el estado del modelo explícitamente. –

Cuestiones relacionadas