Domanda

Ho una firma del metodo di azione [HttpPost] come questa:

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

Ora, in passato (quando non utilizzavo ViewModels, ad esempio R&D), avevo un'implementazione di un metodo Modifica come questo:

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

Che ha funzionato alla grande.

Ma sono confuso su come adattare quanto sopra all'approccio ViewModel.

Se lo faccio:

TryUpdateModel(existingPost)

Con il mio approccio ViewModel, non succede molto. Nessun errore, ma non viene aggiornato nulla perché MVC non saprà come aggiornare un Post da un ExistingPostViewModel (prima che fosse Post -> Post).

Ora sto usando AutoMapper. Quindi ho pensato di poter mappare dal ViewModel al Post, quindi salvare il post.

Ma poi fondamentalmente sovrascrivo tutto. Cosa che non voglio fare e sconfigge il punto del ViewModel ridotto.

Qualcuno può non confondermi?

Questo sembra uno scenario molto comune e sono totalmente perplesso su come le persone lo risolvano. Riesco a vedere solo 3 possibili soluzioni:

  1. Non utilizzare un ViewModel nell'HTTP POST. Come ho detto, l'ho fatto in passato per la ricerca e lo sviluppo e funziona, ma ora vedo come si sono evolute le mie visualizzazioni (convalida, semplicità) e non posso scendere a compromessi solo per il bene di questo problema.

  2. Non utilizzare TryUpdateModel. Forse, ma allora come potrei unire le modifiche?

  3. Usa da sinistra a destra. Uffa. Ma al momento questo sembra essere il modo in cui mi sto appoggiando.

Qualcuno, per favore, mi dia la soluzione n.4! :)

A proposito, sto usando ASP.NET MVC 3, Razor ed Entity Framework.

È stato utile?

Soluzione

In realtà ho corso in questo esatto problema in un progetto che sto lavorando attualmente.Per quanto non fossi un fan, ho finito per fare l'approccio sinistro a destra e mappando manualmente i miei dati del mirino alla mia entità.

L'unica cosa bella di questo approccio è che ti dà più controllo.Da quando ho iniziato a utilizzare più quadritorie composte, dove hai effettivamente campi da più di un'unica entità nel tuo mirino, ha iniziato a rendere più senso fare le cose in questo modo.

Sto anche usando Automapper, e hai assolutamente ragione, diventa imbarazzante quando stai cercando di fare una semplice operazione di aggiornamento.Vorrei avere qualche soluzione super cletente per te, ma il "vecchio stile" sembra prendere il lavoro fatto meglio per il lavoro che ho fatto.

Altri suggerimenti

Per cose semplici in cui non è necessario eseguire alcun controllo prima di implementare l'aggiornamento, ciò che si sta facendo va bene (db.get (), e quindi aggiornare).

Quando le cose si complicano, devi caricare l'entità, quindi selezionare e applicare le modifiche dell'utente dal modello di visualizzazione, proprietà per proprietà.In questi casi, si finisce per scrivere metodi di aggiornamento, che ottiene i nuovi dati come input, quindi si carica l'entità esistente, quindi si confrontano gli stati e si intraprendono le azioni richieste in base ai dati del modello di visualizzazione.In realtà in questo caso, probabilmente non avrai un metodo Update ma avrai comportamenti, come CancelPost, AddComment, EditPost (che registra anche il motivo della modifica), AddTagsToPost ecc.

Non sono sicuro che questo possa aiutare, ma per me funziona.Ho la mia tabella di dominio sottostante come oggetto visitatore.Il mio viewmodel contiene l'oggetto Visitor più un paio di IEnumerables per i menu a discesa.

    [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");

    }

UpdateModel funziona con il mio viewmodel a causa della stringa "Visitor" che gli dice quali valori confrontare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top