反序列化MandrillApp Webhook响应

Abl*_*lue 3 c# json json.net mandrill

据称MandrillApp API 使用mime类型发送JSON编码的消息数组application/x-www-form-urlencoded.

我遇到的问题是收到的数据如下:

mandrill_events=%5B%7B%22event%22%3A%22send%22
%2C%22msg%22%3A%7B%22ts%22%3A136510999...etc
Run Code Online (Sandbox Code Playgroud)

网址解码是:

mandrill_events=[{"event":"send","msg":{
"ts":1365109999,"subject"...etc
Run Code Online (Sandbox Code Playgroud)

我尝试将此字符串反序列化为表示JSON数据的类,但JSON.NET反序列化器会发出错误.

m = JsonConvert.DeserializeObject<MandrillEvents>(s);
Run Code Online (Sandbox Code Playgroud)

例外

解析值时遇到意外的字符:m.路径'',第0行,第0位.

根据我的想法,我认为mandrill_events=字符串的部分无效.

  • 该字符串是否应该反序列化?
  • 反序列化时是否有一个我缺少的选项?
  • 我该怎么做呢?

Des*_*tar 7

mandrill_events=是无效的JSON.如果你拿出来,你应该能够解析它.

string validJson = originalText.Replace("mandrill_events=", ""); 
var m = JsonConvert.DeserializeObject<MandrillEvents[]>(validJson);
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,我们需要查看更多文本以确定其他什么是无效的JSON.JSON很棒,因为它只有一些简单的数据类型.Object,Array,Boolean,String,Integer等.有关所有有效类型的信息,请参见http://json.org/.

正如Brian Rogers所提到的,你也在反序列化为错误的类型(你有一个对象数组,而不是一个对象).

如果要检查整个json字符串是否有效,可以使用

JArray array = JArray.Parse(validJson);
Run Code Online (Sandbox Code Playgroud)

如果你不确定你可以使用

JToken token = JToken.Parse(validJson);
Run Code Online (Sandbox Code Playgroud)

它适用于对象,数组和值.我仍然会说反序列化到模型中会更好,因为你得到了强大的输入,但这至少可以确保你在尝试构建模型之前拥有有效的JSON.


Visual Studio 2012有一个非常酷的功能,如果您复制有效的JSON文本,请单击编辑> 粘贴为JSON类,它实际上将JSON粘贴为有效的C#类,然后您可以将其反序列化.这使得从复杂的JSON构建POCO模型比手动操作更容易,更不容易出错.


回答你的问题

您是否能够评论为什么他们会像他们一样发送回复?

我认为这很奇怪,并且在客户端上做了更多工作以便能够解析/读取他们的响应.您可以使用JSON表示几乎所有数据,这就是为什么它是Web API的数据交换格式的流行选择.所有现代语言都有很好的JSON配对.它是普遍的,很好理解.当您想出任何自定义格式来发送需要客户端编写自己的解析器或甚至使用正则表达式的数据时,您就会重新发明轮子IMO.在这种情况下,他们将一种格式嵌入到另一种格式中,这仍然非常难看,并阻止您使用单个解析器.

就WHY而言,它可能是为了向后兼容.他们最初将他们的API暴露为application/x-www-form-urlencoded并且不想破坏现有客户端,因此他们继续使用它但嵌入了JSON对象.从他们的文档(mandrillapp.com/api/docs/webhooks.JSON.html)看起来所有响应都是JSON,你可以仔细检查你使用的是正确的url,还是你在请求中发送了accept:application/json头.这是告诉服务器要回JSON响应的常见HTTP方式.