web-dev-qa-db-fra.com

Redirection ASP.NET MVC avec le modèle

J'ai actuellement une méthode dans mon contrôleur qui accepte une collection de formulaires, enregistre les données, puis affiche les données dans une page "Détails". Pour le moment, le code ressemble actuellement à quelque chose comme:

[HttpPost]
public ActionResult Create(PersonModel person)<br>
{
    if (person.IsValid())
    {
        person.additionalData = "Person created successfully";
        return View("Details", person);
    }
}

Le problème est que le retour de la vue Détails de cette manière conserve l'URL mysite/Person/Create - idéalement, je voudrais que l'URL soit mysite/Person/Details/IdGoesHere.

Je suis sûr que cela doit être possible. Évidemment, je pourrais utiliser Response.Redirect, mais cela ne me permet pas de passer le modèle à la vue. Pour autant que je sache, je ne peux pas passer le modèle en utilisant RedirectToAction?

Merci pour l'aide.

EDIT: Pour confirmer - le modèle produit par l'action Créer est différent de celui par défaut créé par l'action Détails. Par conséquent, effectuer une redirection directe vers Action et transmettre l'ID ne fonctionne pas car le modèle produit n'est pas correct. Pour donner plus de contexte, le modèle de l'action Créer contient une valeur supplémentaire disant 'Personne créée avec succès', si je redirige vers l'action Détails, ce message n'est pas présent dans le modèle.

39
user460667

Directement depuis ma propre application:

public ActionResult Create(Booking item)
{
    if (ModelState.IsValid)
    {
        int newID = _tasks.Create(item);
        // NEW section to emulate model being populated for use in Details view
        TempData["additionalData"] = "Person created successfully";
        return RedirectToAction("Details", new { id = newID });
    }
    else
    {
        return View();
    }
}

alors, votre action "Détails" ne pourrait-elle pas ressembler à ceci:

public ActionResult Details(int id)
{
    var item = _tasks.GetByKey(id);
    var additionalData = TempData["additionalData"];
    if(item != null) {
        if(additonalMessage!=null)
        {
            item.additionalData = additionalData;
        }
        return View(item);
    }
    else
        return View("Notfound");
}

ne pourriez-vous pas adopter une approche similaire ??

Vous pouvez simplement faire la redirection selon la convention et avoir un indicateur défini (sur les données temporaires comme ci-dessus) qui donne ce message? Le drapeau de tempadata serait UNIQUEMENT défini dans l'action Créer, donc ne se produirait que lors de la création d'un nouvel objet "personne". ainsi l'action Details ne l'afficherait que comme conséquence de l'action Create

35
jim tollan

Vous pouvez compléter ce qui a été proposé (utiliser RedirectToAction et routage) avec l'utilisation de TempData

[HttpPost]
public virtual ActionResult Create(IEnumerable<OrderItem> orderItems)
    {
        if (orderItems.Count() == 0)
        {
            return RedirectToAction("NoOrderItems");
        }
        else
        {
            TempData["orderItems"] = orderItems;
            return RedirectToAction("Confirm");
        }
    }

    [HttpGet]
    public virtual ActionResult Confirm()
    {
        var orderItems = TempData["orderItems"] as IEnumerable<OrderItem>;
        if (orderItems == null || orderItems.Count() == 0)
        {
            this.InvokeHttp404(ControllerContext.HttpContext);
        }

        return View(orderItems);
    }

Je l'utilise pour des éléments que je ne souhaiterais peut-être pas recréer lors de demandes ultérieures ou qui persistent encore dans la base de données. Avec cela, je n'ai pas besoin de contrôles nuls à mon avis, car la page de confirmation ne peut être "obtenue" que s'il existe des données pour cela.

9
Jonathan Bates

Cela devrait vous amener au modèle de détails, en passant l'ID avec lui.

return RedirectToAction("Details", new { id = person.PersonID });
9
Marko

N'oubliez pas que vous pouvez également adopter l'approche de type sécurisé de MvcContrib et faire

return this.RedirectToAction<MyController>(c => c.Details(person.PersonID));
8
Yannis