有时是数组有时是对象时反序列化JSON

Deserializing JSON when sometimes array and sometimes object(有时是数组有时是对象时反序列化JSON)

本文介绍了有时是数组有时是对象时反序列化JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 JSON.NET 库反序列化从 Facebook 返回的数据时遇到了一些麻烦.

I'm having a bit of trouble deserializing data returned from Facebook using the JSON.NET libraries.

从一个简单的墙贴返回的 JSON 如下所示:

The JSON returned from just a simple wall post looks like:

{
    "attachment":{"description":""},
    "permalink":"http://www.facebook.com/permalink.php?story_fbid=123456789"
}

为照片返回的 JSON 如下所示:

The JSON returned for a photo looks like:

"attachment":{
        "media":[
            {
                "href":"http://www.facebook.com/photo.php?fbid=12345",
                "alt":"",
                "type":"photo",
                "src":"http://photos-b.ak.fbcdn.net/hphotos-ak-ash1/12345_s.jpg",
                "photo":{"aid":"1234","pid":"1234","fbid":"1234","owner":"1234","index":"12","width":"720","height":"482"}}
        ],

一切都很好,我没有问题.我现在遇到了一个来自移动客户端的简单墙贴,其中包含以下 JSON,而反序列化现在因这一个帖子而失败:

Everything works great and I have no problems. I've now come across a simple wall post from a mobile client with the following JSON, and deserialization now fails with this one single post:

"attachment":
    {
        "media":{},
        "name":"",
        "caption":"",
        "description":"",
        "properties":{},
        "icon":"http://www.facebook.com/images/icons/mobile_app.gif",
        "fb_object_type":""
    },
"permalink":"http://www.facebook.com/1234"

这是我反序列化的类:

public class FacebookAttachment
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public string Href { get; set; }
        public FacebookPostType Fb_Object_Type { get; set; }
        public string Fb_Object_Id { get; set; }

        [JsonConverter(typeof(FacebookMediaJsonConverter))]
        public List<FacebookMedia> { get; set; }

        public string Permalink { get; set; }
    }

如果不使用 FacebookMediaJsonConverter,我会收到错误消息:无法将 JSON 对象反序列化为类型System.Collections.Generic.List`1[FacebookMedia]".这是有道理的,因为在 JSON 中,Media 不是一个集合.

Without using the FacebookMediaJsonConverter, I get an error: Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[FacebookMedia]'. which makes sense, since in the JSON, Media is not a collection.

我发现这篇文章描述了一个类似的问题,所以我试图走这条路:反序列化JSON,有时value是一个数组,有时是"(空字符串)

I found this post which describes a similar problem, so I've attempted to go down this route: Deserialize JSON, sometimes value is an array, sometimes "" (blank string)

我的转换器看起来像:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
     if (reader.TokenType == JsonToken.StartArray)
          return serializer.Deserialize<List<FacebookMedia>>(reader);
     else
          return null;
}

效果很好,只是我现在遇到了一个新异常:

Which works fine, except I now get a new exception:

在 JsonSerializerInternalReader.cs 内部,CreateValueInternal():反序列化对象时出现意外令牌:PropertyName

Inside JsonSerializerInternalReader.cs, CreateValueInternal(): Unexpected token while deserializing object: PropertyName

reader.Value 的值是永久链接".我可以在 switch 中清楚地看到 JsonToken.PropertyName 没有案例.

The value of reader.Value is "permalink". I can clearly see in the switch that there's no case for JsonToken.PropertyName.

我需要在转换器中做一些不同的事情吗?谢谢你的帮助.

Is there something I need to do differently in my converter? Thanks for any help.

推荐答案

JSON.NET 的开发人员最终帮助了项目 codeplex 网站.这是解决方案:

The developer of JSON.NET ended up helping on the projects codeplex site. Here is the solution:

问题是,当它是一个 JSON 对象时,我没有读取过去的属性.这是正确的代码:

The problem was, when it was a JSON object, I wasn't reading past the attribute. Here is the correct code:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.TokenType == JsonToken.StartArray)
    {
        return serializer.Deserialize<List<FacebookMedia>>(reader);
    }
    else
    {
        FacebookMedia media = serializer.Deserialize<FacebookMedia>(reader);
        return new List<FacebookMedia>(new[] {media});
    }
}

James 也很友好地为上述方法提供了单元测试.

James was also kind enough to provide unit tests for the above method.

这篇关于有时是数组有时是对象时反序列化JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:有时是数组有时是对象时反序列化JSON

基础教程推荐