反序列化使用Newtonsoft Json.Net IEnumerable的类 [英] Deserialize to IEnumerable class using Newtonsoft Json.Net

查看:175
本文介绍了反序列化使用Newtonsoft Json.Net IEnumerable的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在使用Json.Net对JSON序列化类的这样的一个项目:

I have a project that is currently using Json.Net for Json deserialization classes like these:

public class Foo {
    public Guid FooGuid { get; set; }
    public string Name { get; set; }
    public List<Bar> Bars { get; set; }
}

public class Bar {
    public Guid BarGuid { get; set; }
    public string Description { get; set; }
}

到目前为止,它工作正常。

So far it works fine.

要进行迭代简单的在一个点上我做了类实现的IEnumerable&LT;酒吧&GT; 是这样的:

To make iteration simpler at one point I made Foo class implement IEnumerable<Bar> like this:

public class Foo : IEnumerable<Bar> {
    public Guid FooGuid { get; set; }
    public string Name { get; set; }
    public List<Bar> Bars { get; set; }

    public IEnumerator<Bar> GetEnumerator()
    {
        return Bars.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class Bar {
    public Guid BarGuid { get; set; }
    public string Description { get; set; }
}

但随后失败反序列化对象。该错误是混乱的,因为它说,它无法反序列化 FooGuid 字段,但除去的IEnumerable 接口工作了。

But then it fails deserializing the object. The error is confusing, as it said that it cannot deserialize FooGuid field, but removing the IEnumerable interface works again.

现在的问题是在这两个MonoTouch的和MonoDroid环境的模拟器或设备一样。

The problem is the same in both MonoTouch and MonoDroid environments in simulator or device.

任何有关如何使它工作的线索?

Any clue about how to make it work?

加code重现此问题:

Added code to reproduce this issue:

public static class Tests {
    public static void SerializeAndDeserializeFoo() {
        // Serialize and deserialize Foo class
        var element = new Foo
        {
            FooGuid = Guid.NewGuid(),
            Name = "Foo name",
            Bars = new List<Bar> {
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" },
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" },
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" }
            }
        };

        var serializedObject = JsonConvert.SerializeObject(element);
        Console.WriteLine("Serialized Foo element: {0}", serializedObject);

        // Exception if Foo implements IEnumerable
        var deserializedObject = JsonConvert.DeserializeObject<Foo>(serializedObject);
        Console.WriteLine("Foo deserialization worked!");
    }

    public static void SerializeAndDeserializeEnumerableFoo() {
        // Serialize and deserialize Foo class
        var element = new EnumerableFoo
        {
            FooGuid = Guid.NewGuid(),
            Name = "Foo name",
            Bars = new List<Bar> {
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" },
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" },
                new Bar { BarGuid = Guid.NewGuid(), Description = "Bar description" }
            }
        };

        var serializedObject = JsonConvert.SerializeObject(element);
        Console.WriteLine("Serialized EnumerableFoo element: {0}", serializedObject);

        try {
            // Exception if Foo implements IEnumerable
            var deserializedObject = JsonConvert.DeserializeObject<EnumerableFoo>(serializedObject);
            Console.WriteLine("EnumerableFoo deserialization worked!");
        }
        catch (Exception e){
            Console.WriteLine("EnumerableFoo deserialization failed!");
            throw;
        }
    }
}

public class EnumerableFoo : IEnumerable<Bar> {
    public Guid FooGuid { get; set; }
    public string Name { get; set; }
    public List<Bar> Bars { get; set; }

    public IEnumerator<Bar> GetEnumerator()
    {
        return Bars.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class Foo {
    public Guid FooGuid { get; set; }
    public string Name { get; set; }
    public List<Bar> Bars { get; set; }
}

public class Bar {
    public Guid BarGuid { get; set; }
    public string Description { get; set; }
}

示例项目:<一href="https://www.dropbox.com/s/27i58aiz71dylkw/IEnumerableJson.zip">https://www.dropbox.com/s/27i58aiz71dylkw/IEnumerableJson.zip

推荐答案

从到<​​a href="http://james.newtonking.com/json/help/?topic=html/SerializationGuide.htm">的Json .NET文档:

的IEnumerable,List和Array

.NET列表和.NET阵列(继承自IEnumerable类型)被转换为JSON阵列。由于JSON阵列只支持一个范围值,而不是属性,任何额外的属性和.NET的集合声明的字段不是序列化。当JSON数组不想要的JsonObjectAttribute可以放在实现IEnumerable强制类型序列化为一个JSON对象而不是.NET类型的情况。

.NET lists (types that inherit from IEnumerable) and .NET arrays are converted to JSON arrays. Because JSON arrays only support a range of values and not properties, any additional properties and fields declared on .NET collections are not serialized. In situations where a JSON array is not wanted the JsonObjectAttribute can be placed on a .NET type that implements IEnumerable to force the type to be serialized as a JSON object instead.

在换句话说,因为你的类实现的IEnumerable&LT; T&GT; ,Json.Net认为这是一个列表。为了解决这个问题,简单地用 [JSONObject的] 属性装饰你的类。这将迫使Json.Net序列化和反序列化作为一个普通的类,它是你想在这种情况下,是什么。

In other words, since your class implements IEnumerable<T>, Json.Net thinks it is a list. To get around this, simply decorate your class with the [JsonObject] attribute. This will force Json.Net to serialize and deserialize it as a normal class, which is what you want in this case.

[JsonObject]
public class EnumerableFoo : IEnumerable<Bar>
{
    ...
}

这篇关于反序列化使用Newtonsoft Json.Net IEnumerable的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆