4 Stimmen

Handhabung von Postanfragen in ASP.NET MVC

Vor kurzem habe ich angefangen, mit MVC zu arbeiten, vorher habe ich "klassisches" ASP.NET verwendet.

Nach der Verwendung von Ruby on Rails (RoR), frage ich mich, wie POST-Anfrage Handhabung in MVC ähnlich wie RoR funktioniert zu implementieren. In RoR verwendet man die Post Methode, so dass Sie nur eine Funktion für eine Ansicht benötigen.

In ASP.NET MVC muss ich 2 separate Funktionen verwenden für GET und für POST Ich muss also dieselben Daten zweimal initialisieren, und ich möchte nicht, dass sich etwas in meinem Code wiederholt.

Wie kann ich überprüfen, ob die Anfrage POST mit einer Methode?

Aktualisierung:

Die Lösung ist gefunden: Ich muss Request.HttpMethod verwenden.

Ich danke Ihnen!

9voto

Ich bin auf diese Frage gestoßen, weil ich das Gleiche wissen wollte. Im Folgenden finden Sie eine ausführliche Beschreibung meiner Situation und der Lösung, die ich verwendet habe (die die anderen Antworten hier verwendet). Ursprünglich habe ich versucht, zwei getrennte Methoden zu verwenden, aber ich bin auf ein Problem gestoßen, als die Methodensignaturen dieser Methoden identisch wurden.

Ich habe eine Seite, die Berichtsdaten anzeigt. Oben auf der Seite befindet sich ein Formular mit einigen Feldern, in denen der Benutzer Berichtsparameter wie Startdatum, Enddatum usw. angeben kann.

Ursprünglich habe ich zwei getrennte Methoden für die Get- und die Post-Methode entwickelt, um dieses Problem zu lösen. Die Post-Methode würde den Browser an die Get-Methode weiterleiten, so dass alle angegebenen Parameter dem Query-String hinzugefügt würden und der Browser den Benutzer nicht mit einem Dialog auffordern würde, die eingegebenen Daten erneut zu senden, wenn er die Seite aktualisiert. Hinweis: Später habe ich festgestellt, dass ich dies erreichen könnte, indem ich das Methodenattribut meines Formularelements auf "Get" setze, aber ich denke, dass ein Controller idealerweise nicht wissen sollte, wie eine Ansicht implementiert ist, daher ist das meiner Meinung nach irrelevant.

Als ich diese beiden Methoden entwickelte, fand ich mich schließlich in einer Situation wieder, in der die Methodensignaturen identisch wurden. Außerdem wurde mein Code für diese beiden Methoden fast identisch, so dass ich beschloss, sie in einer einzigen Methode zusammenzufassen und nur das Anfrageverb zu prüfen, damit ich etwas anderes tun kann, wenn die Anfrage kein "Get" ist. Ein Beispiel für meine beiden Methoden ist unten dargestellt:

    // this will not compile because the method signatures are the same

    public ActionResult MyReport(DateRangeReportItem report)
    {
        // if there are no validation errors and the required report parameters are completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // retrieve report data and populate it on the report model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        return View(report);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
            // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
            return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
        }
        else
        {
            // there were validation errors, or the report parameters are not yet complete
            return View(report);
        }
    }

Warum akzeptiere ich ein Modellobjekt als Parameter für meine get-Methode? Der Grund dafür ist, dass ich die bereits in das Modellobjekt integrierte Validierungslogik nutzen wollte. Wenn jemand direkt zu meiner Seite navigiert und alle Parameter bereits im Query-String angegeben sind, möchte ich die Berichtsdaten abrufen und auf der Seite anzeigen. Wenn jedoch die in der Abfragezeichenfolge angegebenen Parameter ungültig sind, sollen auf der Seite auch Überprüfungsfehler angezeigt werden. Indem ich mein Modellobjekt als Parameter einsetze, wird das MVC-Framework automatisch versuchen, es zu füllen, und wird alle Validierungsfehler ohne zusätzliche Arbeit meinerseits erfassen.

Ich habe die anderen Antworten für diese Frage veröffentlicht, um eine RequestHttpVerb-Eigenschaft auf eine Basis-Controller-Klasse in meinem Projekt zu erstellen:

    public HttpVerbs RequestHttpVerb
    {
        get { return (HttpVerbs)Enum.Parse(typeof(HttpVerbs), this.Request.HttpMethod, true); }
    }

Meine konsolidierte Methode sieht also wie folgt aus:

    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        // check if there are any validation errors in the model
        // and whether all required report parameters have been completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // this is unnecessary if the form method is set to "Get"
            // but within the controller I do not know for sure if that will be the case in the view
            if (HttpVerbs.Get != this.RequestHttpVerb)
            {
                // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
                // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
                return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
            }

            // there were no validation errors and all required report parameters are complete
            // retrieve report data and populate that data on the model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        // display the view with the report object
        // Any model state errors that occurred while populating the model will result in validation errors being displayed
        return View(report);
    }

Das ist meine derzeitige Lösung für dieses Problem. Ich würde es vorziehen, die Request.HttpMethod-Eigenschaft nicht überprüfen zu müssen, um festzustellen, ob ich die Umleitung durchführen muss, aber ich habe keine andere Lösung für mein Problem gesehen. Ich hätte auch zwei getrennte Methoden für die Bearbeitung von Get- und Post-Anfragen verwenden können, aber die identische Methodensignatur verhinderte dies. Ich hätte es vorgezogen, meine Post-Action-Handler-Methode umzubenennen, um den Methodensignaturkonflikt zu vermeiden, und dem MVC-Framework mit einem Mechanismus zu signalisieren, dass meine umbenannte Methode weiterhin die Aktion "MyReport" verarbeiten sollte.

5voto

JonoW Punkte 13361

Sie brauchen nur dann getrennte Methoden für GET und POST, wenn sich ihre Methodensignaturen unterscheiden. Es gibt keinen Grund, warum eine Aktionsmethode nicht sowohl GET- als auch POST-Methoden verarbeiten kann.

Wenn Sie wissen müssen, ob es ein GET oder POST war, könnten Sie mit Request.HttpMethod in Ihrer Aktion überprüfen, aber ich würde empfehlen, eine separate Methode mit dem Attribut [AcceptVerbs(HttpVerbs.Post)] zu verwenden, wie von den anderen Postern vorgeschlagen.

3voto

David Morton Punkte 15950

Sie überprüfen nicht in ASP.NET MVC. Sie dekorieren Ihre Methode mit der [AcceptVerbs(HttpVerbs.Post)] Attribut, um anzugeben, dass die Methode nur für "post" gilt, und das Modell in der Methode zu akzeptieren, die für die Bearbeitung von "post" verwendet wird.

Ich würde dringend empfehlen, die Komplettlösung für NerdDinner um mehr über das ASP.NET MVC-Framework zu erfahren.

1voto

Darin Dimitrov Punkte 990883

Sie können einen Blick auf die Request.HttpMethod Eigentum.

0voto

Amitabh Punkte 54879

Die korrekte Vorgehensweise ist die Verwendung von ModelBinding während der Post-Anforderung.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(EmployeeViewModel model)
{
 //validate data, save employee, handle validation errors...
}

Auf diese Weise müssen Sie Ihre Daten nicht erneut eingeben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X