• If you need help or want to discuss things, you now can also join us on our Discord Server!

DE Http Post - Leerer Body

YasuoMain97

Donor
is awesome!
#1
Ich rufe über den Browser folgende Funktion auf:
JavaScript:
$.post("api/TrackCounter", {"track": "test"}, function (data){ console.warn(data)})
Diese Daten landen einwandfrei beim Controller.

Poste ich aber über die http-Funktion des Sinusbots Daten kommen im Controller keine Daten an.

JavaScript:
http({
            'method': strMethod,
            'url': 'https://soulcraft.bz/api/' + strFunc,
            'timeout': 6000,
            'maxSize': 1024 * 1024 * 5,
            'body': sendData,
            'headers': {
                'Content-Type': 'application/json',
                'Content-Length': sendData.length
            }
        }, function (error, response) {
            
            if (response.statusCode != 200) {
                engine.log(response.statusCode);
                engine.log(error);
                return;
            }

            var res;
            try {
                res = JSON.parse(response.data);
            } catch (err) {
                engine.log(err.message);
            }

            if (res === undefined) {
                engine.log("Error in JSON!");
                return;
            }
            
            engine.log(res);
        });
Vor dem Post war das Format der Daten noch richtig (2. Zeile).
Code:
2018-04-24T08:43:57+02:00 Soulcraft :50 System.Exception: Empty Track at Soulcraft.Controllers.TrackCounterController.Post(String track)
2018-04-24T08:43:57+02:00 Soulcraft :18 {"track":"Perfect Strangers ft. JP Cooper"}
Welche Umwandlungen oder Anpassungen werden am JSON Objekt vorgenommen? Kann das leider schlecht debuggen, wenn die Daten bereits abgesendet wurden, aber noch nicht beim Controller angekommen sind. Theoretisch würde ich erwarten, dass die Daten dann auch 1 zu 1 ankommen.

Oder ist beim Post Aufruf etwas falsch. Gibt es alternativen, mit denen ich ein Post machen kann?

Vielen Dank für jede Antwort!
 

flyth

is reticulating splines
Staff member
Developer
Contributor
#2
Was ist denn dein sendData? Ggf. mach mal ein JSON.stringify(sendData).
 

mxschmitt

Gave up the fitness studio
Staff member
V.I.P.
is awesome!
Contributor
Insider
#3
Hallo,

du nutzt als http methode die Variable "strMethod", wieso nicht direkt einfach "POST"?

Zudem musst du, wenn du JSON verschicken willst, es noch serialisieren. =>
Code:
'body': JSON.stringify(sendData),
Best regards

Max
 

YasuoMain97

Donor
is awesome!
#4
Mein sendData ist
JavaScript:
var sendData = JSON.stringify(obj);
Und laut Log ist es auch im richtigen Format
Code:
{"track":"Perfect Strangers ft. JP Cooper"}
 

flyth

is reticulating splines
Staff member
Developer
Contributor
#5
Du kannst mal dem request object
debug: true,
hinzufügen. Dann siehst du auf der Konsole, was passiert.

Code:
http({
            'method': strMethod,
            'url': 'https://soulcraft.bz/api/' + strFunc,
            debug: true,
...
 

YasuoMain97

Donor
is awesome!
#6
Ja okay, habe das jetzt einfach mal Quick and Dirty mir aus dem Request Body gezogen und deserialisiere es von Hand. Kann damit erstmal leben, aber ich habe auch nichts dagegen, wenn es in Zukunft Unterstützung für JSON Objekte geben würde. Eventuell würde ich das Feature sogar bestellen, wenn es möglich ist.
 

flyth

is reticulating splines
Staff member
Developer
Contributor
#7
Es gibt JSON-Unterstützung in jeder Form (serialisieren, deserialisieren) - schlussendlich ists ja nachher auch nur ein Text, der geschickt wird.
Du musst also lediglich an der richtigen Stelle serialiseren, damit es funktioniert.

Ja okay, habe das jetzt einfach mal Quick and Dirty mir aus dem Request Body gezogen und deserialisiere es von Hand.
Kannst du das noch mal genauer erklären? Das klingt nämlich genau so, wie man es machen sollte. Ich verstehe auch gerade nicht, _wo_ du es von Hand deserialisierst - wenn das nämlich in Java in deinem Soulcraft-Ding ist, dann haben wir da relativ wenige Aktien dran ;)
 

YasuoMain97

Donor
is awesome!
#8
So wie ihr es mir beigebracht habt funktioniert der Post nur, wenn man einen ganzen String übergibt. Ich habe einen MVC Controller, der dann das Backend darstellt und auch die Daten für das Frontend wieder bereitstellt.

Theopraktisch sollte es dann so funktionieren, dass vom Controller das deserialisieren übernommen wird und dann als Parameter für die Funktion die einzelnen Properties des JSON Objektes übergeben werden oder gleich ein ganzes Modell (wenn das doch mehr ist als eine einzelne Information).

Wenn ich also ein JSON Objekt mit der Property Track übergebe brauche ich nur noch in meiner Methode, die Post-Requests empfängt den Parameter Track hinzufügen.

JSON:
{
    "track": "Track title"
}
C#:
        [HttpPost]
        public object Post(string track){
            object result = new object();
            return Json(result)
        }
Aber die Daten kommen nicht als JSON an, sondern als Text. Daher ist dort noch ein weiterer Schritt notwendig in diesem Falle, der sonst wegfallen würde: das Deserialisieren.
 

flyth

is reticulating splines
Staff member
Developer
Contributor
#9
Dieses ganze MVC usw. sind alles Aufsätze von irgendwas, was hier nur eine untergeordnete Rolle spielt - wichtig zu verstehen, ist, dass die Kommunikation zwischen deiner Software und dem Bot per HTTP stattfindet - und da gibt es kein MVC und auch kein JSON. Da gibt es nur Text.
Durch headers im HTTP-Request kannst du der empfangenden Seite mitgeben, was für eine Art Daten du da gerade überträgst usw. (bspw. durch den Content-Type header) - und wenn die Software es unterstützt, dann _kann_ sie solche Header automatisch auswerten und den (Body-)Text entsprechend (also bspw. als JSON) interpretieren (was in dem Fall dem Deserialisieren entspricht).

Du musst also quasi nur herausfinden, wann deine Software wie Daten interpretiert, wenn du von irgendwelchen Automatismen Gebrauch machen willst. Eine andere verbreitete Art, Daten per POST zu schicken, ist über url-encoding. Vielleicht unterstützt dein Framework (automatisiert) nur diese Methode und dein $.post() überträgt es genau so.
 
#10
Ich bin in genau das gleiche Problem geraten. Mache ich mit Postman oder einem anderen Server eine PATCH-Anfrage an meinen Webservice funktioniert alle tadellos. Über die Scripting API des Sinusbots kommt lediglich ein leerer Body zurück. Aktiviert man das Logging werden keine Angaben zu den Headers gemacht.
Daraufhin habe ich versucht mit der alten Scripting API eine http-Anfrage zu senden:
JavaScript:
sinusbot.http({
                "method": "POST",
                "url": "http://...",    
                "timeout": 6000,    
                "headers": {      
                    "Content-Type": "application/json"     
                }    
             }, ...
Mit Erfolg! Anscheinend hat die neue Scripting-API ein Problem die angegebenen Header mitzuschicken.
 

Multivitamin

V.I.P.
V.I.P.
is awesome!
is uber awesome!
Contributor
Insider
Tier III
#11
Habe ich gerade auch noch getestet und kann bestätigen dass headers sowie body leer bleiben

ausserdem in dem insider build ist die response struktur fehlerhaft
JavaScript:
const http = require("http")
http.simpleRequest({
    method: "POST",
    url: "http://localhost:10000",
    headers: "Content-Type: application/json",
    body: JSON.stringify({test: 1})
}, (err, res) => {
    engine.log(Object.keys(res), res.statusCode, String(res.statusCode))
})
geloggt wird:
["data","headers","status","statusCode"] <nil> 200
 

Similar threads