Question

J'ai une signature de méthode d'action [HttpPost] comme celle-ci:

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

Maintenant, dans le passé (quand je n'utilisais pas ViewModels, par exemple R&D), j'avais une implémentation d'une méthode Edit comme celle-ci:

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

Ce qui a très bien fonctionné.

Mais je ne sais pas comment adapter ce qui précède à l'approche ViewModel.

Si je fais ceci:

TryUpdateModel(existingPost)

Avec mon approche ViewModel, il ne se passe pas grand chose. Aucune erreur, mais rien n'est mis à jour car MVC ne saura pas comment mettre à jour un Post à partir d'un ExistingPostViewModel (avant qu'il ne soit Post -> Post).

Maintenant, j'utilise AutoMapper. J'ai donc pensé que je pourrais mapper du ViewModel au Post, puis enregistrer le message.

Mais ensuite, je suis en train de tout remplacer. Ce que je ne veux pas faire et qui bat le point de vue réduit ViewModel.

Quelqu'un peut-il me dissiper?

Cela semble être un scénario très courant, et je suis totalement perplexe quant à la manière dont les gens résolvent ce problème. Je ne vois que 3 solutions possibles:

  1. N'utilisez pas de ViewModel dans HTTP POST. Comme je l'ai dit, je l'ai fait dans le passé pour la R&D et cela fonctionne, mais maintenant je vois comment ma vue a évolué (validation, simplicité), et je ne peux pas faire de compromis pour le simple plaisir de ce problème.

  2. N'utilisez pas TryUpdateModel. Peut-être, mais comment puis-je fusionner les modifications?

  3. Utilisez de gauche à droite. Pouah. Mais pour le moment, cela semble être la façon dont je me penche.

Quelqu'un, s'il vous plaît, donnez-moi la solution n ° 4! :)

BTW, j'utilise ASP.NET MVC 3, Razor et Entity Framework.

Était-ce utile?

La solution

J'ai rencontré exactement le même problème dans un projet sur lequel je travaille actuellement.Même si je n'en étais pas fan, j'ai fini par faire l'approche de gauche à droite et mapper manuellement mes données de modèle de vue sur mon entité.

La seule chose intéressante à propos de cette approche est qu'elle vous donne plus de contrôle.Depuis que j'ai commencé à utiliser davantage de modèles de vue composés, où vous avez en fait des champs de plus d'une entité dans votre modèle de vue, il est devenu plus logique de faire les choses de cette façon.

J'utilise également AutoMapper, et vous avez absolument raison, cela devient gênant lorsque vous essayez de faire une simple opération de mise à jour.J'aurais aimé avoir une solution de contournement super intelligente pour vous, mais la "méthode à l'ancienne" semble faire le meilleur travail pour le travail que j'ai fait.

Autres conseils

Pour des choses simples où vous n'avez pas à exécuter de contrôles avant d'implémenter la mise à jour, ce que vous faites est correct (db.get (), puis update).

Lorsque les choses se compliquent, vous devez charger l'entité, puis sélectionner et appliquer les modifications de l'utilisateur à partir du modèle de vue, propriété par propriété.Dans ces cas, vous finissez par écrire des méthodes de mise à jour, qui récupèrent les nouvelles données en entrée, puis vous chargez l'entité existante, comparez les états et effectuez les actions requises en fonction des données du modèle de vue.En fait, dans ce cas, vous n'aurez probablement pas de méthode de mise à jour, mais vous aurez des comportements, comme CancelPost, AddComment, EditPost (qui enregistre également la raison de la modification), AddTagsToPost, etc.

Je ne sais pas si cela aidera, mais cela fonctionne pour moi.J'ai ma table de domaine sous-jacente en tant qu'objet visiteur.Mon viewmodel contient l'objet Visiteur plus quelques IEnumerables pour les listes déroulantes.

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

    }

Le UpdateModel fonctionne avec mon viewmodel car la chaîne "Visiteur" lui indique les valeurs à comparer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top