• If you need help or want to discuss things, you now can also join us on our Discord Server!
  • A first preview of the unlimited version of SinusBot can be found in the Upcoming Changes thread. A version for Windows will follow, but we don't have a release date, yet.

DE Http Post - Leerer Body

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
Was ist denn dein sendData? Ggf. mach mal ein JSON.stringify(sendData).
 

mxschmitt

Moderator
Staff member
is awesome!
V.I.P.
is uber awesome!
Contributor
Insider
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
 
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
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,
...
 
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
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 ;)
 
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
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.
 

Digiii

Member
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

Well-Known Member
Tier III
is awesome!
V.I.P.
is uber awesome!
Contributor
Insider
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
 
Top