我的模块中有一条路线,应该接受代表博客帖子的JSON主体。问题是请求正文不是seralized。如果我调试,我会在请求中看到以下值:
this.Request.Body.Length: 93
x.Keys.Count: 0
路线
Post["/Blog"] = x =>
{
var post = this.Bind<Post>(); //Breakpoint
PostService.Save(post);
return post;
};
HTTP请求
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" } }
答案 0 :(得分:15)
您的代码没有问题,问题是您已经包装了JSON:
您的对象有一个名为Post
的属性,然后它有实际的帖子。
将您的身体更新为:
{ "Title":"Hello", "Content":"World", "Created":"2014-04-26" }
这很可能与Post
对象上的属性匹配。
以下是对客户端的序列化,而不是问题的要求
您需要添加Accept
标题。
我在这里写过关于Nancy Conneg的文章:
http://www.philliphaydon.com/2013/04/22/nancyfx-revisiting-content-negotiation-and-apis-part-1/
您的方案不起作用,因为您只告诉服务器您的内容是什么,而不是您期望的内容。
使用Chrome插件 - 邮差,您可以测试您的方案,类似于:
通过将Accept
标头应用为application/json
,系统会将序列化返回的内容。
或者,您可以在网址末尾添加.json
以将其作为JSON返回:
http://yoursite.com/blog.json
这将强制JSON序列化程序启动。
如果您想要始终返回JSON,可以使用.AsJson()
Post["/Blog"] = x =>
{
var post = this.Bind<Post>(); //Breakpoint
PostService.Save(post);
return Response.AsJson(post);
};
注意,如果您要返回dynamic
类型,那么您需要投放它:return Response.AsJson((object)post);