将对象序列化为数组

时间:2014-01-02 02:56:06

标签: c# json.net

我有一个C#对象。我想将它序列化为数组而不是键值映射。

我的C#课程:

[JsonArray()]
public class Foo
{
    [JsonProperty(Order = 1)]
    public Boolean Bar = true;

    [JsonProperty(Order = 2)]
    public Boolean Baz = false;
}

所需的JSON输出:

[true,false]

实际的JSON输出(如果我删除顶部的JsonArray属性):

{"Bar":true,"Baz":false}

我在复杂的对象层次结构中有大量的对象,我需要将其序列化为数组而不是键值映射。我更喜欢一种解决方案,它不要求进行序列化的事情知道什么是序列化。我希望能够在顶级对象上调用JsonConvert.SerializeObject(myThing)并让所有子对象由于它们自身的属性而正确序列化。

目前,我的所有对象都实现了IEnumerable,然后我手动教他们每个人如何以正确的顺序返回属性但这会导致在C#中工作时出现混乱,因为intellisense试图为我提供所有的LINQ操作在对象上,即使它们都不合适。

我相信,虽然我不知道如何向Foo添加一个指向另一个知道如何序列化Foo的类的属性。像[JsonConverter(FooSerializer)]然后FooSerializer之类的东西会实现JsonConverter。但是,我很难找到关于如何使用JsonConverter进行序列化的大量信息,人们提出的大多数问题似乎都与反序列化有关。

2 个答案:

答案 0 :(得分:4)

以下是编写此类转换器的方法。

[JsonConverter(typeof(FooConverter))]
public class Foo
{
    public bool Bar { get; set; }
    public bool Baz { get; set; }
}
public class FooConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var foo = value as Foo;
        var obj = new object[] { foo.Bar, foo.Baz };
        serializer.Serialize(writer, obj);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var arr = ReadArrayObject(reader, serializer);
        return new Foo
        {
            Bar = (bool)arr[0],
            Baz = (bool)arr[1],
        };
    }

    private JArray ReadArrayObject(JsonReader reader, JsonSerializer serializer)
    {
        var arr = serializer.Deserialize<JToken>(reader) as JArray;
        if (arr == null || arr.Count != 2)
            throw new JsonSerializationException("Expected array of length 2"); 
        return arr;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Foo);
    }
}

当涉及序列化/反序列化时,我发现转换为对象的泛型表示更容易,序列化程序可以根据需要识别和解释它。

序列化(写入)很简单,因为您希望将Foo对象的表示形式更改为值数组,将其转换为值数组并将其序列化。

一般来说,反序列化(阅读)可能会有点困难。但同样,方法也是一样的。你期待一个布尔值数组。反序列化为数组并对其进行操作以创建对象。如果您愿意,我可以在这里执行一些验证。

有了这个,您应该能够非常轻松地转换为JSON字符串和从JSON字符串转换。

var str = "[[true,true],[true,false]]";
var foos = JsonConvert.DeserializeObject<Foo[]>(str);
var serialized = JsonConvert.SerializeObject(foos);

答案 1 :(得分:0)

Json.NET中的序列化是documented here,包括JsonConverterAttribute类