Customizing Json.NET serialization: turning object into array to avoid repetition of property names

前端 未结 6 1651
半阙折子戏
半阙折子戏 2020-12-30 00:11

I\'m sending large amounts of different JSON graphs from a server to a client (I control both) and they all contain a pathological case: a large array of homogeneous (same t

6条回答
  •  青春惊慌失措
    2020-12-30 00:39

    No need for custom JSON converters. Just make your class implement IEnumerable. Json.NET will then serialize your data as an array instead of an object.

    For instance, instead of...

    // will be serialized as: {"Key1":87,"Key2":99}
    public class Foo
    {
        public string Key1;
        public string Key2;
    }
    

    ...write this:

    // will be serialized as: [87,99]
    public class Foo : IEnumerable
    {
        public string Key1;
        public string Key2;
    
        IEnumerator IEnumerable.GetEnumerator() => EnumerateFields().GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() => EnumerateFields().GetEnumerator();
        IEnumerable EnumerateFields()
        {
            yield return Key1;
            yield return Key2;
        }
    }
    
    
    

    If you need to apply this strategy to many classes then you can declare an abstract base class to get rid of some of the boilerplate:

    // Base class for objects to be serialized as "[...]" instead of "{...}"
    public abstract class SerializedAsArray : IEnumerable
    {
        IEnumerator IEnumerable.GetEnumerator() =>
            EnumerateFields().GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() =>
            EnumerateFields().GetEnumerator();
        protected abstract IEnumerable EnumerateFields();
    }
    
    // will be serialized as: [87,99]
    public class Foo : SerializedAsArray
    {
        public string Key1;
        public string Key2;
    
        protected override IEnumerable EnumerateFields()
        {
            yield return Key1;
            yield return Key2;
        }
    }
    
        

    提交回复
    热议问题