15

tengo un método [HttpPost] acción de la firma así:¿Cómo actualizar el modelo cuando se vincula a un ViewModel?

[HttpPost] 
public ActionResult Edit(ExistingPostViewModel model) 
{ 
    // Save the edited Post. 
} 

Ahora, en el pasado (cuando no usamos ViewModels, por ejemplo, R & D), tuve una implementación de un método de Editar como esto:

[HttpPost] 
public ActionResult Edit(Post model) 
{ 
    var existingPost = repo.Find(model.Id); 
    TryUpdateModel(existingPost); 
    repo.Save(existingPost); 
    return RedirectToAction("Success", existingPost.Id); 
} 

Lo que funcionó muy bien.

Pero estoy confundido sobre cómo adaptar lo anterior al enfoque de ViewModel.

si hago esto:

TryUpdateModel(existingPost) 

Con mi enfoque de modelo de vista, no sucede gran cosa. No hay errores, pero no se actualiza nada porque MVC no sabrá cómo actualizar un Post desde un ExistingPostViewModel (antes era Post ->Post).

Ahora, estoy usando AutoMapper. Así que pensé que podía mapear desde el ViewModel al Post, luego guardar la publicación.

Pero básicamente estoy básicamente anulando todo. Lo cual no quiero hacer y derrota el punto del modelo definido ViewModel.

¿Alguien puede confundirme?

Esto parece un escenario muy común, y estoy totalmente perplejo en cuanto a cómo las personas resuelven esto. Solo puedo ver 3 soluciones posibles:

  1. No use un ViewModel en HTTP POST. Como dije, hice esto en el pasado para R & D y funciona, pero ahora veo cómo han evolucionado mis View (validación, simplicidad), y no puedo comprometerlo solo por el bien de este problema.

  2. No utilice TryUpdateModel. Posiblemente, pero ¿cómo me fusionaría en los cambios?

  3. Use de izquierda a derecha. Ugh. Pero por el momento, esta parece ser la manera de imponerse.

Alguien por favor dame la solución # 4! :)

Por cierto, estoy usando ASP.NET MVC 3, Razor y Entity Framework.

Respuesta

2

De hecho me encontré con este mismo problema en un proyecto en el que estoy trabajando actualmente. Por mucho que no me gustara, terminé haciendo el enfoque de izquierda a derecha y mapeando manualmente los datos de mi modelo de vista a mi entidad.

Lo único bueno de este enfoque es que le da más control. Desde que empecé a usar viewmodels más compuestos, donde en realidad tienes campos de más de una entidad en tu viewmodel, comenzó a tener más sentido hacer las cosas de esta manera.

También estoy usando AutoMapper, y tiene toda la razón, se pone incómodo cuando intenta hacer una operación de actualización simple. Desearía tener alguna solución súper inteligente para usted, pero la "forma antigua" parece hacer el mejor trabajo para el trabajo que he estado haciendo.

+0

Noooo ... :) No me importa hacer de izquierda a derecha de vez en cuando, pero esto significa que CUALQUIER página de actualización tendrá que hacerlo. Realmente debería haber una forma genérica/simple de hacer esto. Yo uso ViewModel en cada Vista. Entonces cada Vista que requiere una actualización de la base de datos necesita L-R. Además, ahora también necesito una tonelada de campos ocultos. Me duele la cabeza ... :( – RPM1984

+0

Estaba esperando con la esperanza de que alguien más viniera y nos dijera que hay una mejor manera. Pero supongo que no .((1) y aceptado. – RPM1984

0

Para cosas simples donde no tiene que ejecutar ningún control antes de implementar la actualización, lo que está haciendo está bien (db.get(), y luego actualizar).

Cuando las cosas se complican, debe cargar la entidad y luego seleccionar y aplicar los cambios del usuario desde el modelo de vista, propiedad por propiedad. En esos casos, termina escribiendo métodos de Actualización, que obtiene los datos nuevos como entrada, y luego carga la entidad existente, luego compara estados y toma las acciones requeridas en base a los datos del modelo de vista. En realidad, en este caso, probablemente no tendrá un método de actualización, pero tendrá comportamientos, como CancelPost, AddComment, EditPost (que también registra el motivo de edición), AddTagsToPost, etc.

+0

Sí, tengo obtuve métodos de comportamiento como 'AddComment'. Pero esta es una página básica de CRUD donde solo quiero actualizar el objeto existente con los valores que he proporcionado en el ViewModel entrante. Debería ser simple, no puedo creer que tenga que comparar manualmente los estados de las propiedades. Esto también significa que necesitaré campos ocultos en todo el formulario. – RPM1984

0

No estoy seguro si esto ayudará, pero está funcionando para mi. Tengo mi tabla de dominio subyacente como un Objeto de visitante. Mi viewmodel contiene el objeto de visitante más un par de IEnumerables para desplegables.

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit(int id) 

    { 
     Visitor Visitor = new Visitor(); 
     Visitor = db.Visitors.FirstOrDefault(v => v.VisitorID == id); 

     UpdateModel(Visitor, "Visitor"); 

     db.SaveChanges(); 
     return RedirectToAction("Index"); 

    } 

El UpdateModel obras de mi modelo de vista debido a la cadena "Visitante" decir las cosas qué valores a comparar.

Cuestiones relacionadas