2010-01-10 4 views
5

Ma configuration:RenderAction doit-il être utilisé avec des formulaires?

  • avoir une vue d'une route comme: /Pages/Details/2
  • Les détails de la page voir a <% Html.RenderAction("CreatePageComment", "Comments"); %> pour rendre un formulaire de commentaire
  • messages formulaire de commentaire à Comments/CreatePageComment
  • /Comments/CreatePageComment retours RedirectToAction quand un commentaire est créé avec succès
  • Tout cela fonctionne bien

Ma question:

S'il y a une erreur de validation, comment dois-je revenir à /Pages/Detail/1 et montrer l'erreur sous forme de commentaire?

  • Si j'utilise RedirectToAction, il semble que la validation soit difficile; devrais-je même utiliser le modèle Post-Redirect-Get pour les erreurs de validation, au lieu de simplement revenir?
  • Si je retourne View() il me ramène à montrer la vue CreateComment.aspx (avec validation, mais juste un formulaire sur une page blanche), pas le /Pages/Details/2 route qui a appelé le RenderAction.

Si le modèle PRG doit être utilisé, alors je pense que j'ai juste besoin d'apprendre à faire la validation tout en utilisant PRG. Si ce n'est pas — et pour moi cela semble mieux géré en retournant View() — alors je ne sais pas comment obtenir l'utilisateur retourné à la vue initiale, montrant les erreurs de formulaire, tout en utilisant RenderAction. Cela ressemble au jeu où vous tapotez la tête et vous frottez le ventre en même temps. Je n'étais pas bon à celui-là non plus. Je suis nouveau chez MVC, donc c'est probablement le problème ici.

+0

BTW: Je pourrais faire cela en ayant juste un Partial et un POST route/Page/CreateComment, mais cela ne semble pas désordonné? Je veux que mon contrôleur de commentaires gère les commentaires, pas le contrôleur de page. Curieusement, je viens de passer en revue le code du moteur de blog Oxite, et leur contrôleur Post gère l'ajout de commentaires; leur controller Comments n'a même pas d'action Create! –

Répondre

5

Je crois que la réponse est d'utiliser TempData, par exemple:

À mon avis (/ Étapes/Détails) je:

<!-- List comments --> 
<% Html.RenderAction("List", "Comments", new { id = Model.Step.Id }); %> 

<!-- Create new comment --> 
<% Html.RenderAction("Create", "Comments", new { id = Model.Step.Id }); %> 

Dans mon contrôleur commentaires j'ai ma méthode POST:

// POST: /Comments/Create 
    [HttpPost] 
    public ActionResult Create([Bind(Exclude = "Id, Timestamp, ByUserId, ForUserId")]Comment commentToCreate) 
    { 
     if (ModelState.IsValid) 
     { 
      //Insert functionality here 

      return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId }); 

     } 

    //If validation error 
     else 
     { 

      //Store modelstate from tempdata 
      TempData.Add("ModelState", ModelState); 

      //Redirect to action (this is hardcoded for now) 
      return RedirectToAction("Details", "Steps", new { id = commentToCreate.StepId }); 
     } 
    } 

également dans le contrôleur de commentaires est ma méthode GET:

// 
    // GET: /Comments/Create 

    public ActionResult Create(int id) 
    { 

     if (TempData.ContainsKey("ModelState")) 
     { 
      ModelStateDictionary externalModelState = (ModelStateDictionary)TempData["ModelState"]; 
      foreach (KeyValuePair<string, ModelState> valuePair in externalModelState) 
      { 
       ModelState.Add(valuePair.Key, valuePair.Value); 
      } 
     } 
     return View(new Comment { StepId = id }); 
    } 

Cela fonctionne très bien pour moi, mais je vous en serais reconnaissant des commentaires sur que ce soit une bonne pratique, etc.

Aussi, je remarqué que MvcContrib a une décoration ModelStateToTempData qui semble faire, mais d'une manière plus propre . Je vais essayer ça ensuite.

+0

J'ai eu un problème similaire de ce que vous aviez. La solution que vous proposez semble fonctionner, mais je suis curieux de savoir s'il n'y a pas une façon plus propre de le faire. Pour moi, votre solution semble être plus un hack qu'une vraie solution. Je ne sais pas si quelqu'un d'autre a une autre opinion à ce sujet? – Melursus

+0

Ouais, ça me semble hackish, mais c'est tout ce que j'ai pu trouver qui fonctionne. Comme vous, j'accueillerais une solution plus propre. –

+0

Dans ma recherche, je trouve que la bibliothèque MvcContrib a quelque chose appelé SubController qui peut peut-être résoudre ce genre de problème. Je ne regarde pas plus loin, mais ça semble intéressant. – Melursus

Questions connexes