2011-02-09 12 views
7

He estado trabajando en esta aplicación MVC 3 Razor y normalmente utilizo modelos de vista para mis vistas.Acciones del controlador MVC: manejar POST y OBTENER sin código duplicado

Un buen número de mis modelos de vista contienen más información que la entidad en particular con la que estoy interactuando en mi formulario. Así que mi gestor de acciones GET iniciará el modelo de vista y proporcionará a cada propiedad el valor previsto, etc.

En mi controlador de acción POST, verifico si el estado del modelo es válido, si no vuelvo a mostrar el formulario/vista con errores

En mi controlador de acción POST, tengo que copiar el código de mi manejador de acción GET para volver a representar la vista. ¿Cómo puedo implementar mis acciones de controlador para no tener que copiar el código que es responsable de recopilar los datos para el modelo de vista?

He intentado permitir que mi manejador de acciones maneje tanto POST como GET, pero luego tengo los parametros de entrada a tratar. Mi controlador de acción POST tendrá el modelo de vista como un parámetro de entrada, pero para el controlador de acción GET no lo hará.

+1

¿Podría darnos algunos ejemplos del código que está escribiendo en este momento? – marcind

+1

has intentado solo redirigir acción posterior para obtener acción? – frennky

Respuesta

4

En situaciones como estas, creamos constructores para nuestros modelos de vista.

Eche un vistazo a la opción 3 en this post.

+0

+1 este es un enfoque agradable y limpio. –

+0

Aunque el código al que se hace referencia no utiliza el constructor en las acciones de obtención y publicación, como esperaba de acuerdo con mi pregunta original, creo que crear constructores para el modelo de vista es una buena solución para esto. – JBeckton

-1

Su método de acción POST debería ser capaz de simplemente el tipo de modelo de vista como el parámetro, en lugar de todas las piezas de datos individuales. Si el modelo de vista es más complejo de construir, puede escribir un encuadernador para su modelo de vista que pueda hacer ese trabajo más complejo (su método de acción aún tomaría el tipo de máquina virtual como parámetro).

[HttpPost] 
public ViewResult MyAction(MyViewModel model) { 
    // model should now be fully populated; check ModelState.IsValid though in case there are errors (such as the user entering "abc" for an int property) 
} 
7

Su manejador POST puede devolver el ActionResult desde el controlador de GET, de la siguiente manera:

public ActionResult SomePageGet() { 
    var model = new SomePageViewModel(); 

    // Populate ViewModel: 
    ... 

    return View("SomePageGet", model); 
} 

[HttpPost] 
public ActionResult SomePagePost(SomePageViewModel input) { 

    // Validate the model: 
    ... 

    if (!ModelState.IsValid) { 
     // Return the GET page, with error messages: 
     return SomePageGet(); 
    } 

    return View("Success"); 
} 

Desde el ModelState contiene todos los mensajes de error (y de entrada no válida), la página GET les mostrará normalmente.

0

Puede simplemente refactorizar el código común en un método de extensión en la entidad principal en la que está trabajando.

Luego llámelo tantas veces como desee durante su estancia DRY.

No conozco con precisión cuál es la función de ese código común, pero en su mayoría serán datos relacionados para una presentación enriquecida. En ese caso, la solución que prefiero es dejar que la vista cargue los datos adicionales de otra acción utilizando RenderAction, que luego se puede refactorizar a la actualización de la página AJAX quedando DRY y separando las preocupaciones de las acciones.

0

"... me encuentro tener que copiar el código ..."

No entiendo por qué; ¿Por qué no puedes simplemente crear un miembro en tu controlador y llamarlo? No todo en tu controlador debe ser una Acción. Pero es posible que desee ver constructores en su lugar como sugirió @ataddeini.

Cuestiones relacionadas