RedirectToAction in ASP.NET MVC, ohne Anforderungsdaten zu verlieren

123

Bei Verwendung von ASP.NET MVC gibt es Situationen (z. B. das Senden von Formularen), für die möglicherweise eine erforderlich ist RedirectToAction .

Eine solche Situation besteht darin, dass nach dem Senden eines Formulars Validierungsfehler auftreten und Sie zum Formular zurückleiten müssen, die URL jedoch die URL des Formulars widerspiegeln soll, nicht die Aktionsseite, an die es gesendet wird.

Wie POSTkann ich die Daten durch das Formular weiterleiten, da ich die ursprünglich bearbeiteten Daten aus Gründen der Benutzerfreundlichkeit sowie zu Validierungszwecken enthalten muss RedirectToAction()? Wenn ich den Parameter viewData verwende, werden meine POSTParameter in GETParameter geändert .

Matt Mitchell
quelle
Hier ist eine Frage, die ähnlich ist (zum selben Thema), aber anders als diese. Auf jeden Fall könnte es für diejenigen, die an dieser Frage interessiert sind, immer noch von Interesse sein: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann
Warum geben Sie nicht einfach dieselbe Ansicht zurück, wenn ein Fehler auftritt? RedirectToAction wird normalerweise aufgerufen, wenn das Modell gültig ist - oder fehlt mir etwas?!
Niico

Antworten:

81

Die Lösung besteht darin, die TempData-Eigenschaft zum Speichern der gewünschten Anforderungskomponenten zu verwenden.

Zum Beispiel:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Dann können Sie in Ihrer "Formular" -Aktion gehen:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}
Matt Mitchell
quelle
1
RedirectToAction (a => a.Form ()) wird für mich nicht mit MVCv2 kompiliert. Verwenden Sie MVCv3?
ChrisAnnODell
1
Dies war vor MVC1 (2008). Ich glaube, die Lambdas wurden irgendwann entfernt (es gibt ein Codeplex-Projekt MVCContrib, das sie wieder einführt, obwohl Sie in diesem Stadium auch ihr Hilfsattribut verwenden können : stackoverflow.com/questions/1936/… ). In mvc2 sollten Sie in der Lage sein, RedirectToAction ("Form") zu verwenden, dh den Namen als Zeichenfolge, obwohl ich mich locker daran erinnere, dass MVC 2 oder 3 ein Hilfsattribut ähnlich dem in MVCContrib eingeführt hat, wenn Sie suchen möchten.
Matt Mitchell
37

Beachten Sie, dass TempData die Formularsammlung in einer Sitzung speichert. Wenn Ihnen dieses Verhalten nicht gefällt, können Sie die neue ITempDataProvider-Schnittstelle implementieren und einen anderen Mechanismus zum Speichern von temporären Daten verwenden. Ich würde das nicht tun, wenn Sie nicht sicher wissen (über Messung und Profilerstellung), dass die Verwendung des Sitzungsstatus Sie verletzt.

Gehackt
quelle
13

Werfen Sie einen Blick auf MVCContrib , können Sie dies tun:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
Dan
quelle
8

Es gibt einen anderen Weg, der Tempdaten vermeidet. Das Muster, das mir gefällt, beinhaltet das Erstellen einer Aktion sowohl für das ursprüngliche Rendern als auch für das erneute Rendern des ungültigen Formulars. Es geht ungefähr so:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

Das ist mehr oder weniger das Muster. Ein bisschen Pseudo. Mit dieser Option können Sie eine Ansicht erstellen, um das Rendern des Formulars zu übernehmen, die Werte erneut anzuzeigen (da das Formular mit vorherigen Werten gefüllt wird) und Fehlermeldungen anzuzeigen.

Wenn die Buchung für diese Aktion gültig ist, überträgt sie die Kontrolle auf eine andere Aktion.

Ich versuche, dieses Muster im .net-Validierungsframework zu vereinfachen, während wir die Unterstützung für MVC ausbauen.

Däne O'Connor
quelle
Ich verwende auch TempData, das Problem, wie ich es verstehe, mit Ihrer Lösung Deeno ist, dass der Benutzer, wenn er die Seite nach dem Posten ungültiger Daten aktualisieren würde, die Bestätigung "Möchten Sie die Formulardaten erneut senden" erhalten würde. Die Verwendung der TempData-Lösung, wie MattMitchell sagt, beseitigt dieses Problem.
user10479
Cool. Anscheinend hat jemand diese Grundidee auch mit Vorschau 5 bemerkt.
Matt Mitchell
2

Wenn Sie Daten an die umgeleitete Aktion übergeben möchten, können Sie folgende Methode verwenden:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);
lzlstyle
quelle
0

TempData ist die Lösung, die die Daten von Aktion zu Aktion hält.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Aswal
quelle