Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON body is not deseralized by NancyModule

I have a route in my module that is supposed to accept a JSON body representing blog post. Problem is that the request body is not seralized. If I debug I see the following values on the request:

this.Request.Body.Length: 93
x.Keys.Count: 0

The route

Post["/Blog"] = x =>
        {
            var post = this.Bind<Post>(); //Breakpoint

            PostService.Save(post);
            return post;
        };

The HTTP-request

POST /Blog HTTP/1.1
Host: localhost:57888
Content-Type: application/json
Cache-Control: no-cache

{ "Post": { "Title":"Hello", "Content":"World", "Created":"2014-04-26" } }
like image 578
Gabriel Smoljár Avatar asked Apr 26 '14 07:04

Gabriel Smoljár


People also ask

Does nancyfx help with WRT deserialization of JSON request body?

The documentation suggests the NancyFx helps me out WRT deserialization of json request body, but I'm not sure how. See test below to demonstrate: Show activity on this post.

How to deserialize JSON in ASP NET Core?

The JSON will be deserialized using NewtonSoft.Json library in ASP.Net Core. Note: For beginners in ASP.Net MVC Core, please refer my article ASP.Net MVC Core Hello World Tutorial with Sample Program example.

Is the raw body content the same as the JSON content?

So the raw body content returned by Body.AsString () obviously (and by definition) is not the same as the json content (e.g. because of the quotation marks that have to be removed). Let me also post both some client code and yet another version of the server code to boil it further down by removing the newline from the equation.

What's wrong with my JSON code?

There's nothing wrong with your code, the problem is you've wrapped your JSON: Your object has a property called Post, then it has the actual post. Update your body to look like:


1 Answers

Deserialization:

There's nothing wrong with your code, the problem is you've wrapped your JSON:

Your object has a property called Post, then it has the actual post.

Update your body to look like:

{ "Title":"Hello", "Content":"World", "Created":"2014-04-26" }

This most likely matches the properties on your Post object.


Below is serialization to the client, not what the question was asking for


Serialization:

You need to add an Accept header.

I've written about Nancy Conneg here:

http://www.philliphaydon.com/2013/04/22/nancyfx-revisiting-content-negotiation-and-apis-part-1/

Your scenario doesn't work because you're only telling the server what your content is, not what you expect in return.

Accept

Using the Chrome Plugin - Postman, you can test your scenario similar to this:

enter image description here

By applying the Accept header as application/json the content returned will be serialized.

.json url

Alternatively, you can can add .json to the end your URL to return it as JSON:

http://yoursite.com/blog.json

This will force the JSON serializer to kick in.

.AsJson()

If you want to always return JSON regardless, you can return your result using .AsJson()

Post["/Blog"] = x =>
{
    var post = this.Bind<Post>(); //Breakpoint

    PostService.Save(post);
    
    return Response.AsJson(post);
};

Note, if you're returning a dynamic type then you will need to cast it: return Response.AsJson((object)post);

like image 183
Phill Avatar answered Oct 27 '22 07:10

Phill