Laden...

Wie bekomme ich einen Rückgabewert des Post-Aufrufs mittels Javascript(JQuery)?

Letzter Beitrag vor 13 Jahren 13 Posts 3.353 Views
Wie bekomme ich einen Rückgabewert des Post-Aufrufs mittels Javascript(JQuery)?

Hi,

ich mache gerade meine ersten Erfahrungen mit Javascript und der jQuery Library. Hierzu möchte ich eine schon vorhandene ASP-NET Razor Page alternativ als einen jQuery Dialog anbieten. Soweit klappt das auch schon.
Problem: Wenn ich den folgenden Post Befehl aufrufe, fehlt mir ein Rückgabewert. Success wird grundsätzlich immer ausgeführt. Wenn z.B. die Server-seitige Validierung fehlschlägt, würde ich gerne darauf reagieren. Wie manage ich das Handling zwischen Web-Page und Javascript beim Post grundsätzlich?

                    $.post("/Mandanten/Mandant/Aendern/Dialog/" + id,
                        $("#MandantForm").serialize(),
                        function () {
                            mandantDialog.dialog("close");
                            LoadList();
                        }
                    );

public JsonResult MyFunction(  )
{
    return Json( new { Message = "Foo" }, JsonRequestBehavior.AllowGet );
}
$.post(action, {}, function (data) {
    alert( data.Message );
    }, "json");

Hi,

Du benutzt hier noch das Schema einer alten jQuery Version.
Seit 1.5 gibt eine Ajax Abfrage ein jqxhr-Objekt zurück.



var jqxhr  = $.post('url', {data:value})
.success(function(returnValue) {
   // Success
})
.error(function() {
   // Error / Abort
})
.complete(function() {
   // Complete
});

Diese Variante ist deutlich übersichtlicher.

* Du kannst im Controller bei falschen Validierungen auch den HttpStatusCode ändern und diesem im complete-Absatz der jQuery Abfrage behandeln.
Oder Du packst eben alles in ein Json-Objekt, oder Du gibst direkt eine generierte PartialView zurück.
Success wird immer ausgeführt, wenn die Abfrage erfolgreich war. Die Logik der Abfrage ist dabei irrelevant; es zählt nur der StatusCode, den der Server zurück gibt (200, 404, 500...)

* Du solltest auch die id besser über die Post-Daten weitergeben, nicht in der URL.
{ "id": id, "form" : $("#MandantForm").serialize() }
Zusätzlich solltest Du beim serialize immer beachten, dass hier keine zwei Forms inneinander sein dürfen!

Gruß

public JsonResult MyFunction(  )  
{  
    return Json( new { Message = "Foo" }, JsonRequestBehavior.AllowGet );  
}  
$.post(action, {}, function (data) {  
    alert( data.Message );  
    }, "json");  

Danke für die Antwort. Habe ich aber leider überhaupt nicht verstanden. Vielleicht könntest du das mir mit noch ein paar erklärenden Worten ergänzen.

Er möchte Dir damit sagen, dass Du in der Action, die Du per Ajax aufrufst, einen Rückgabewert definieren musst, der aussagt, ob die Ausführung korrekt war oder nicht. Er nimmt hierbei die Datenvariante Json, da sich diese bei Javascript anbietet.

@Abt: Danke für deine Hinweise. Langsam (sehr langsam) nähere ich mich bei mir dauert das etwas. Das mit Json lassen wir erst einmal (heute) weg, ich muss erst einmal grundsätzliches verstehen. Zu deinen Verbesserungen.

**1. .post Aufruf Parameter ohne Json:**Das

                    var jqxhr = $.post("/Mandanten/Mandant/Aendern/Dialog/" + id,
                    $("#MandantForm").serialize())

habe ich ihn

                    var jqxhr = $.post("/Mandanten/Mandant/Aendern/Dialog", 
                      {"id" : id, "form" : $("#MandantForm").serialize()})

geändert. Habe ich auch verstanden. Auf der Server Seite habe ich aber das Problem, dass meine function

@functions
{
    public static void GetMandant(Mandant mandant)
    {
        mandant.Firmenbezeichnung = Request["Mandant.Firmenbezeichnung"].Trim();
        mandant.Name = Request["Mandant.Name"].Trim();
        mandant.Vorname = Request["Mandant.Vorname"];
        mandant.Namenszusatz = Request["Mandant.Namenszusatz"];
        mandant.Titel = Request["Mandant.Titel"];
    }
}

nichts mehr finden. Klar mit

Request["form"]

bekomme ich wieder mein Dictionary, aber muss ich jetzt eine zwischen Variable (Dictionary) einführen, in der ich das Dictionary reinpacke und auf diese anstatt auf Request zugreifen, denn Request["form"][""Mandant.Name"] geht ja leider nicht. Da gibt es doch bestimmt schon was oder?

2. ResponseText auswerten.

                        .complete(
                            function (xhr) {
                                alert("complete");
                                if (xhr.status == 200) {
                                    mandantDialog.dialog("close");
                                    LoadList();
                                }
                                else {
                                    mandantDialog.html(xhr.responseText);
                                }
                            }

Im xhr.responseText habe ich grundsätzlich alle Informationen stehen die ich brauche. Nur brauch ich davon nur einen Teil (#MandantForm) Wie kann ich die Daten aus responseText rausholen und wie setze ich die neuen Daten in mandantDialog? Ist das mit

mandantDialog.html(xhr.responseText);

so korrekt?

zu 1)

Wenn Deine Form ein Model bildet - was hier absolut korrekt ist - dann muss der Parametername übereinstimmen.
Der Parameter "mandant" ist dann bereits mit allen Formfeldern gefüllt, sofern die Form-Elemente (input...) mit Name und ID der jeweiligen Property entsprechen. Du musst hier nicht manuell den Request abfragen!
Damit dies automatisch geschieht, verwendet man die HTML UI Helper.

Gemäßt Deiner Action müsste es lauten:

var jqxhr = $.post("/Mandanten/Mandant/Aendern/Dialog",{"id" : id, "mandant" : $("#MandantForm").serialize()})

Ist es korrekt, dass Du die Action von "GetMandant" zeigen wolltest?! Die ID wertest Du gar nicht aus.
Ebenso kannst Du die Action mittels [HttpPost] für Post-Only-Requests deklarieren, was hier durchaus sinn macht.

zu 2)
Der complete() Event ist der falsche Event, um den erfolgreichen Rückgabewert zu behandeln.
Hierzu benutzt man success(function(data)) {}.
data ist hierbei der Content, den der Server zurück gibt. Kann HTML sein, kann Json sein, kann alles mögliche sein.

complete() nutzt man, zB um 404 oder 500 abzufangen, da error() auch ausgeführt wird, wenn der Ajax-Request mit absicht abgebrochen wird (zB um mehrere Requests zu vermeiden).

zu 1)

Wenn Deine Form ein Model bildet - was hier absolut korrekt ist - dann muss der Parametername übereinstimmen.
Der Parameter "mandant" ist dann bereits mit allen Formfeldern gefüllt, sofern die Form-Elemente (input...) mit Name und ID der jeweiligen Property entsprechen. Du musst hier nicht manuell den Request abfragen!
Damit dies automatisch geschieht, verwendet man die HTML UI Helper.

OK! Model = Form automatisch verstanden! Meine Forms besteht aber nicht nicht nur aus Mandant, sondern auch aus Anschrift und weiten Modellen. Also muss ich wohl doch manuell meine

mandant.Firmenbezeichnung = Request["Mandant.Firmenbezeichnung"].Trim();

machen. Brauche ich jetzt eine eigenes Dictionary, um "form" reinzupacken oder gibt was "kürzeres"?

zu 2)
Der complete() Event ist der falsche Event, um den erfolgreichen Rückgabewert zu behandeln.
Hierzu benutzt man success(function(data)) {}.
data ist hierbei der Content, den der Server zurück gibt. Kann HTML sein, kann Json sein, kann alles mögliche sein.

complete() nutzt man, zB um 404 oder 500 abzufangen, da error() auch ausgeführt wird, wenn der Ajax-Request mit absicht abgebrochen wird (zB um mehrere Requests zu vermeiden). complete habe ich nur genommen, da du es im vorigen Post als alternative angepriesen hast. Grundsätzlich ist das aber schon klar. Der wichtige Punkt hierbei war:

Im xhr.responseText habe ich grundsätzlich alle Informationen stehen die ich brauche. Nur brauch ich davon nur einen Teil (#MandantForm) Wie kann ich die Daten aus responseText rausholen und wie setze ich die neuen Daten in mandantDialog? Vielleicht so?

C#-Code:
mandantDialog.html(????);

so korrekt?

Wie bekomme ich eigentlich Intellisense für jQuery in meine .js Dateien? Bei den Razor Pages funktioniert es! Visual Studio Prof 2010 kein WebMatrix!

Nein, die HTML Helper können auch mehrere Models verschiedenen Typs zuordnen. Schau sie dir einfach mal an. Jedes Model muss aber separat in der Action definiert werden.
Alternativ (was ich auch empfehlen würde, wenn Du es schon so machst) mach für jedes Model eine eigene Form - **aber nicht ineinander **- und dann jede Form serialisiert per Ajax übergeben. Ist nicht schwer.

Zu Deim complete():
Du nimmst den Inhalt der Rückgabe (data) und setzt Sie einfach in das HTML Element, das Du haben willst;
zB $('div#MyResultMessage').html(data);
Je nachdem was Du eben zurück bekommst - das weißt aktuell nur Du 😉

Achtung: Wenn Du ganze Formen ersetzten willst - das würde ich über Ajax lassen, da würde ich die ganze Seite neu laden, da manche Browser (IE6 / FF <3.5) Probleme mit dem Ersetzen einer Form im DOM haben.

jQuery hat eigene Intellisense-Dateien, die man runterladen kann. Enden mit -vsdoc.js. Diese werden dann über ///reference=... im JS-File bekannt gemacht. Google einfach danach.
Aber Javascript Intellisense in Visual Studio möchte ich mal als Krankheit beziffern; nutze ich auch nicht. Finde ich umständlich.

Sorry, komm da nicht mehr mit. Brauche dafür wohl noch zeit. Aber beantworte mir doch mal eine Frage. Ich habe xhr.responseText (string). Die beinhaltet z.B. meine ganze WebSite. Wie kann ich mittels Javascript oder jQuery einen Teil z.B. "#MandantForm" in einen neuen string raus`extrahieren?

Tut mir leid, ich weiß gar nicht was Du mit dem responseText willst.

Ich hab Dir versucht zu sagen, dass Du im Complete() nur den HttpStatusCode abfragen musst, weil Du für alles andere Success() oder Error() hast.
Du ersetzt im complete() nichts und wie man den Inhalt der Rückgabe der Ajax Abfrage in das gewünschte HTML Element kopiert / schreibt hab ich Dir im letzten Post genannt.
Ich weiß nicht, was Du mit "string raus extrahieren" meinst....