C# ASP.NET MVC retour à la Page précédente

J'ai une méthode D'édition de base dans mon contrôleur qui redirige vers une liste de niveau supérieur ("Index") lorsque l'édition réussit. Comportement Standard après échafaudage MVC.

J'essaie de changer cette méthode D'édition pour rediriger vers la page précédente (pas D'Index). Puisque ma méthode D'édition n'utilisait pas le paramètre d'entrée mappé par défaut "id", j'ai d'abord essayé de l'utiliser pour passer dans l'URL précédente.

Dans ma méthode Edit "get", j'ai utilisé cette ligne pour saisir l'URL précédente et cela a fonctionné bien:

ViewBag.ReturnUrl = Request.UrlReferrer;

J'ai ensuite envoyé cette URL de retour à la méthode Edit "post" en utilisant ma balise de formulaire comme ceci:

@using (Html.BeginForm(new { id = ViewBag.ReturnUrl }))

Maintenant, c'est l'endroit où les roues se sont tombées. Je n'ai pas pu obtenir l'URL analysée à partir du paramètre id correctement.

*** MISE À JOUR: RÉSOLU ***

En utilisant L'exemple de Garry comme guide, j'ai changé mon paramètre de " id "à" returnUrl " et utilisé un champ caché pour passer mon paramètre (au lieu de la balise de formulaire). Leçon appris: utilisez uniquement le paramètre " id " comment il était destiné à être utilisé et gardez-le simple. Il fonctionne maintenant. Voici mon code mis à jour avec des notes:

Tout d'abord, je récupère L'URL précédente en utilisant Request.UrlReferrer comme je l'ai fait la première fois.

    //
    // GET: /Question/Edit/5

    public ActionResult Edit(int id)
    {
        Question question = db.Questions.Find(id);
        ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
        ViewBag.Answers = db.Questions
                            .AsEnumerable()
                            .Select(d => new SelectListItem
                            {
                                Text = d.Text,
                                Value = d.QuestionId.ToString(),
                                Selected = question.QuestionId == d.QuestionId
                            });
        // Grab the previous URL and add it to the Model using ViewData or ViewBag
        ViewBag.returnUrl = Request.UrlReferrer;
        ViewBag.ExamId = db.Domains.Find(question.DomainId).ExamId;
        ViewBag.IndexByQuestion = string.Format("IndexByQuestion/{0}", question.QuestionId);
        return View(question);
    }

Et je passe maintenant le paramètre returnUrl du modèle à la méthode [HttpPost] en utilisant un champ caché dans le formulaire:

@using (Html.BeginForm())
{
    <input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
    ...

Dans la méthode [HttpPost], nous extrayons le paramètre du champ caché et le redirigeons vers lui....

    //
    // POST: /Question/Edit/5

    [HttpPost]
    public ActionResult Edit(Question question, string returnUrl) // Add parameter
    {
        int ExamId = db.Domains.Find(question.DomainId).ExamId;
        if (ModelState.IsValid)
        {
            db.Entry(question).State = EntityState.Modified;
            db.SaveChanges();
            //return RedirectToAction("Index");
            return Redirect(returnUrl);
        }
        ViewBag.DomainId = new SelectList(db.Domains, "DomainId", "Name", question.DomainId);
        return View(question);
    }
58
demandé sur Jason Enochs 2012-03-19 19:26:36

1 réponses

Je suppose (corrigez-moi si je me trompe) que vous voulez afficher à nouveau la page d'édition si l'édition échoue et pour ce faire, vous utilisez une redirection.

Vous pouvez avoir plus de chance en retournant simplement la vue plutôt que d'essayer de rediriger l'utilisateur, de cette façon vous pourrez utiliser ModelState pour générer des erreurs aussi.

Modifier:

Mise à jour en fonction des commentaires. Vous pouvez placer l'URL précédente dans le viewModel, l'ajouter à un champ caché, puis de l'utiliser à nouveau dans l'action qui enregistre les modifications.

Par exemple:

public ActionResult Index()
{
    return View();
}

[HttpGet] // This isn't required
public ActionResult Edit(int id)
{
   // load object and return in view
   ViewModel viewModel = Load(id);

   // get the previous url and store it with view model
   viewModel.PreviousUrl = System.Web.HttpContext.Current.Request.UrlReferrer;

   return View(viewModel);
}

[HttpPost]
public ActionResult Edit(ViewModel viewModel)
{
   // Attempt to save the posted object if it works, return index if not return the Edit view again

   bool success = Save(viewModel);
   if (success)
   {
       return Redirect(viewModel.PreviousUrl);
   }
   else
   {
      ModelState.AddModelError("There was an error");
      return View(viewModel);
   }
}

La méthode BeginForm pour votre vue n'a pas non plus besoin d'utiliser cette URL de retour, vous devriez pouvoir vous en sortir avec:

@model ViewModel

@using (Html.BeginForm())
{
    ...
    <input type="hidden" name="PreviousUrl" value="@Model.PreviousUrl" />
}

Pour revenir à votre action de formulaire affichant une URL incorrecte, c'est parce que vous passez une URL en tant que paramètre 'id', de sorte que le routage formate automatiquement votre URL avec le chemin de retour.

Cela ne fonctionnera pas car votre formulaire sera affiché dans une action de contrôleur qui ne savoir comment enregistrer les modifications. Vous devez d'abord poster sur votre action de sauvegarde, puis gérer la redirection à l'intérieur.

49
répondu Garry Marsland 2018-04-05 00:15:01