简体   繁体   English

将对象序列化为数组

[英]Serialize Object into Array

I have a C# object. 我有一个C#对象。 I want to serialize it to an array rather than a key-value map. 我想将其序列化为数组而不是键值映射。

My C# class: 我的C#课:

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

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

The desired JSON output: 所需的JSON输出:

[true,false]

The actual JSON output (if I remove the JsonArray attribute at the top): 实际的JSON输出(如果我删除顶部的JsonArray属性):

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

I have a large number of objects in a complex object hierarchy that I need to have serialized as an array rather than key-value map. 我在复杂的对象层次结构中有大量对象,需要将它们序列化为数组而不是键值映射。 I would prefer a solution that doesn't require that the thing doing the serialization know anything about what it is serializing. 我希望有一种解决方案,它不需要进行序列化的事情对序列化的东西有任何了解。 I want to be able to just call JsonConvert.SerializeObject(myThing) on a top level object and have all of the sub-objects serialize correctly due to attributes they have on themselves. 我希望能够仅在顶级对象上调用JsonConvert.SerializeObject(myThing)并由于其自身具有的属性而使所有子对象正确序列化。

Currently, I have all of my objects implement IEnumerable and then I manually teach each one of them how to return the properties in the correct order but this causes confusion when working in C# because intellisense tries to offer me all of the LINQ operations on the object even though none of them are appropriate. 当前,我所有对象都实现IEnumerable,然后我手动教每个对象如何以正确的顺序返回属性,但这在C#中工作时会引起混乱,因为智能感知会尝试向我提供该对象上的所有LINQ操作即使它们都不适合。

I believe it is possible, though I don't know how, to add an attribute to Foo that points at another class that knows how to serialize Foo. 我相信,尽管我不知道如何,但是有可能向Foo添加一个属性,该属性指向另一个知道如何序列化Foo的类。 Something like [JsonConverter(FooSerializer)] and then FooSerializer would implement JsonConverter . [JsonConverter(FooSerializer)]然后是FooSerializer将实现JsonConverter However, I am struggling to find much information on how to use JsonConverter for serialization, most of the questions people ask seem to be related to deserialization. 但是,我正在努力寻找有关如何使用JsonConverter进行序列化的大量信息,人们提出的大多数问题似乎都与反序列化有关。

Here's how you could write such a converter. 这是编写这种转换器的方法。

[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);
    }
}

When it comes to serialization/deserialization, I find it easier to convert to/from a generic representation of your object that the serializer could recognize and interpret it as needed. 当涉及到序列化/反序列化时,我发现更容易与对象的通用表示形式进行转换,使序列化程序可以根据需要识别和解释该对象。

Serializing (writing) was simple, since you wanted to change the representation of your Foo object to an array of values, convert it to an array of values and serialize that. 序列化(写入)很简单,因为您想将Foo对象的表示形式更改为值数组,然后将其转换为值数组并进行序列化。

Deserializing (reading) could be a bit more difficult in general. 通常,反序列化(读取)可能会有点困难。 But again, the approach is the same. 但是同样,方法是相同的。 You're expecting an array of boolean values. 您期望一个布尔值数组。 Deserialize to an array and manipulate that to create your object. 反序列化为数组并对其进行操作以创建对象。 Here you could perform some validations if you wanted to as I've shown. 如我所显示的,您可以在此处执行一些验证。

With this, you should be able to convert to and from JSON strings quite easily. 有了它,您应该能够轻松地在JSON字符串之间来回转换。

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

此处记录了Json.NET中的序列化,包括JsonConverterAttribute类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM