How to de/serialize System.Drawing.Size to object using JSON.Net?

前端 未结 3 375
面向向阳花
面向向阳花 2021-01-13 07:10

I have absolutely no idea how to do this.

Sample class that I use:

class MyClass
{

    private Size _size = new Size(0, 0);

    [DataMember]
    pu         


        
相关标签:
3条回答
  • 2021-01-13 07:35

    You can use JsonProperty, instead of force each individual property into json result everytime.

    public class MyClass
    {
        [JsonProperty("size")]
        public Size size;
    }
    

    And this is your Size class

    public class Size
    {
        public Size(int w, int h)
        {
            this.Width = w;
            this.Height = h;
        }
    
        [JsonProperty("width")]
        public int Width
        {
            get;
            set;
        }
        [JsonProperty("height")]
        public int Height
        {
            get;
            set;
        }
    }
    

    And this is how you access it

            MyClass w = new MyClass{ size = new Size(5, 7) };
            string result = JsonConvert.SerializeObject(w);
    

    This is what you get

    {"Size":{"width":5,"height":7}}
    

    This way, everytime you add new property in your Size class or even MyClass class, you just need put the JsonProperty attribute on top of it.

    0 讨论(0)
  • 2021-01-13 07:49

    Here is a simple JsonConverter you can use to make System.Drawing.Size serialize the way you want:

    using System;
    using System.Drawing;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    public class SizeJsonConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(Size));
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Size size = (Size)value;
            JObject jo = new JObject();
            jo.Add("width", size.Width);
            jo.Add("height", size.Height);
            jo.WriteTo(writer);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jo = JObject.Load(reader);
            return new Size((int)jo["width"], (int)jo["height"]);
        }
    }
    

    To use the converter, you just need to pass an instance of it to JsonConvert.SerializeObject as shown below:

    MyClass widget = new MyClass { Size = new Size(80, 24) };
    string json = JsonConvert.SerializeObject(widget, new SizeJsonConverter());
    Console.WriteLine(json);
    

    This will give the following output:

    {"Size":{"width":80,"height":24}}
    

    Deserialization works the same way; pass an instance of the converter to DeserializeObject<T>:

    string json = @"{""Size"":{""width"":80,""height"":24}}";
    MyClass c = JsonConvert.DeserializeObject<MyClass>(json, new SizeJsonConverter());
    Console.WriteLine(c.Size.Width + "x" + c.Size.Height);
    

    Output:

    80x24
    
    0 讨论(0)
  • 2021-01-13 07:49

    Just as a quick add-on to Brian Rogers's answer, in the (somewhat common?) case of the Size being an internal variable inside a larger class you are serializing / de-serializing. This might be trivial, but as I'm new to Newtonsoft's JSON parser, it took me some googling to find the right tag.

    Long story short, if your class uses Size as part of it and you'd like to use the above converter. Assume you have the class called Agent that has Size as part of it's definitions, you should do something like this:

    public class Agent
    {
            [JsonConverter(typeof(SizeJsonConverter))]
            public Size size = new Size();
            public long time_observed = 0;
    }

    Notice that the the tag name is still JsonConverter, but the type of it is the converter sub-class you created from the snippet of the accepted answer.

    Hope that saves some newbie like me a few minutes of Googling.

    0 讨论(0)
提交回复
热议问题