Nancy (C#): How do I get my post data?
Asked Answered
H

5

26

I'm using Corona SDK to post data to my C# server:

headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["Accept-Language"] = "en-US"

local body = "color=red&size=small"

local params = {}
params.headers = headers
params.body = body

network.request( host .. "/UpdateHand", "POST", nwListener, params )

I receive a message on the server:

  Post["/UpdateHand"] = x =>
        {
            Console.WriteLine("Received ...");
            return "Ok";
        };

But when I check the data (when I put a breakpoint on it) I don't see where my data is locaded (i.e. the params.body or params.headers). How can I extract this information?

I should POST it correctly according to the documentation on Corona: http://docs.coronalabs.com/daily/api/library/network/request.html

Hambley answered 26/7, 2014 at 10:22 Comment(2)
If you don't want to use model binding, check out this answer https://mcmap.net/q/535766/-nancyfx-posting-json-nancy-dynamicdictionary-is-emptySwainson
Corona____ :) Getting popular.Footage
T
38

The post data is in

this.Request.Body

If you have suitable type you can deserialize your data to it using model binding:

var x = this.Bind<YourType>();
Thickening answered 26/7, 2014 at 11:35 Comment(4)
Thanks, I do not have a suitable type for the moment so I did the first one. My output is, when I do var b = this.Request.Body, is "Nancy.IO.RequestStream". Shouldn't that receive the body as it is being sent?Hambley
Ok, so this seems to give some of the desired output: var id = this.Request.Body; byte[] data = new byte[10]; id.Read(data, 0, 5); Console.WriteLine(System.Text.Encoding.Default.GetString(data));Hambley
If memory serves there is a AsString extension method for RequestStream, so you can get the body as a string by doing this.Request.Body.AsString()Thickening
@ChristianHorsdal that's in the Nancy.Extensions namespaceNephrotomy
D
18

There is a Nancy extension for this. You will need to include the namespace for it.

using Nancy.Extensions;
var text =  Context.Request.Body.AsString();

I like how concise this is, part of Nancy's super-duper easy path.

But a word of caution! This method leaves the stream at the end, so subsequent calls will return empty string. To fix this, always reset the stream immediately afterwards, like so:

Request.Body.Seek(0, SeekOrigin.Begin);

Nancy 2.0 is supposed to correct this so that the stream position is reset by default.

https://github.com/NancyFx/Nancy/pull/2158

Durer answered 1/2, 2017 at 17:33 Comment(2)
Using Nancy 2.0.0 - but Context.Request.Body is a System.IO.Stream - so no AsString available :(Benedictbenedicta
Ian - it should be in Nancy.Extensions.Durer
B
8

This actually works great:

var body = this.Request.Body; 
int length = (int) body.Length; // this is a dynamic variable
byte[] data = new byte[length]; 
body.Read(data, 0, length);             
Console.WriteLine(System.Text.Encoding.Default.GetString(data));
Battement answered 8/3, 2015 at 13:40 Comment(0)
A
3

For Nancy 2.0.0, Request.Body is a Stream rather than a RequestStream, so doesn't have an AsString method. However, this seems to work:

using (var reqStream = RequestStream.FromStream(Request.Body))
{
    var body = reqStream.AsString();
    // ... do stuff with body
}
Assuming answered 7/11, 2018 at 15:10 Comment(0)
H
1

Ideally getting your post data could be accomplished with a simple Bind() call. However, I've seen inconsistent results when using a Bind in a post call such that I've resorted to using the scheme outlined above.

I've seen various discussions about Nancy Bind() working and not working... I've seen both with Post but cannot explain the inconsistency. Where I saw it function properly was where I could guarantee the body of the request was managed as follows:

        var data = Encoding.ASCII.GetBytes (postData);

        request.Method = "POST";
        request.ContentType = "application/json";
        request.ContentLength = data.Length;

        using (var stream = request.GetRequestStream ()) {
            stream.Write (data, 0, data.Length);
        }

However, when sending data that should have been similarly handled (though I couldn't confirm) through WSO2 infrastructure (data serialized as a JSON event dictionary sent to a service proxy), Bind failed while the method above succeeded.

Homemaker answered 13/5, 2016 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.