Merge two objects during serialization using json.net?

前端 未结 1 1965
花落未央
花落未央 2020-12-06 10:50

I met a situation as below could anybody help me achieve as below?

For Example, if I have the class:-

public class Sample
{
    public String name {g         


        
相关标签:
1条回答
  • 2020-12-06 11:17

    You can create anonymous object and serialize it:

    var sample = new Sample { 
        name = "Bob", 
        myclass = new MyClass { 
                    p1 = "x", 
                    p2 = "y" 
                  }};
    
    string json = JsonConvert.SerializeObject(new { 
                     sample.name, 
                     sample.myclass.p1, 
                     sample.myclass.p2 
                  });
    

    Result

    {"name":"Bob","p1":"x","p2":"y"}
    

    But I suggest you either use default serialization of your Sample class, or create class which will be serialized into your format (i.e. move MyClass properties into Sample).

    UPDATE: You can use custom converter, which flattens object and serializes all inner objects properties as top level object properties:

    public class FlattenJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, 
            JsonSerializer serializer)
        {
            JToken t = JToken.FromObject(value);
            if (t.Type != JTokenType.Object)
            {
                t.WriteTo(writer);
                return;
            }
    
            JObject o = (JObject)t;
            writer.WriteStartObject();
            WriteJson(writer, o);
            writer.WriteEndObject();
        }
    
        private void WriteJson(JsonWriter writer, JObject value)
        {
            foreach (var p in value.Properties())
            {
                if (p.Value is JObject)
                    WriteJson(writer, (JObject)p.Value);
                else
                    p.WriteTo(writer);
            }
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, 
           object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return true; // works for any type
        }
    }
    

    Usage:

    string json = JsonConvert.SerializeObject(sample, new FlattenJsonConverter());
    

    Or you can simply hide anonymous type creation into custom converter, if you need this behavior for one type only:

    public class SampleJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, 
            object value, JsonSerializer serializer)
        {
            Sample sample = (Sample)value;
            JToken t = JToken.FromObject(new { 
                          sample.name, 
                          sample.myclass.p1, 
                          sample.myclass.p2 
                       });
    
            t.WriteTo(writer);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType,
            object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Sample);
        }
    }
    
    0 讨论(0)
提交回复
热议问题