Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- namespace ConsoleApp1
- {
- public class JsonFlatAttribute : Attribute
- {
- }
- public class FlatJsonConverter : JsonConverter
- {
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- writer.WriteStartObject();
- WriteObject(writer, value, serializer);
- writer.WriteEndObject();
- }
- private void WriteObject(JsonWriter writer, object value, JsonSerializer serializer)
- {
- var t = JToken.FromObject(value);
- var flatNames = new List<string>();
- if (t.Type == JTokenType.Object)
- {
- var type = value.GetType();
- foreach (var propertyInfo in type.GetProperties())
- {
- var flatAttr = propertyInfo.GetCustomAttribute(typeof(JsonFlatAttribute));
- if (flatAttr != null) flatNames.Add(propertyInfo.Name.ToLower());
- }
- foreach (var token in t.Children())
- {
- if (token.Type == JTokenType.Property && flatNames.Contains(((JProperty) token).Name.ToLower()))
- {
- foreach (var child in token.Children())
- {
- WriteObject(writer, child.Value<object>(), serializer);
- }
- }
- else
- {
- WriteObject(writer, token.Value<object>(), serializer);
- }
- }
- }
- else
- {
- t.WriteTo(writer);
- }
- }
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- var jObject = JObject.Load(reader);
- var value = objectType.GetConstructor(new Type[] { }).Invoke(new object[] { });
- return ReadObject(objectType, jObject, value);
- }
- private object ReadObject(Type objectType, JObject jObject, object value)
- {
- var flatNames = new List<string>();
- foreach (var propertyInfo in objectType.GetProperties())
- {
- var flatAttr = propertyInfo.GetCustomAttribute(typeof(JsonFlatAttribute));
- if (flatAttr != null)
- {
- var obj = propertyInfo.PropertyType.GetConstructor(new Type[] { }).Invoke(new object[] { });
- foreach (var property in obj.GetType().GetProperties())
- {
- var method = typeof(JToken).GetMethod("Value").MakeGenericMethod(property.PropertyType);
- var val = method.Invoke(jObject, new object[] { property.Name.ToLower() });
- property.SetValue(obj, val);
- }
- propertyInfo.SetValue(value, obj);
- }
- else
- {
- foreach (var property in value.GetType().GetProperties())
- {
- var method = typeof(JToken).GetMethod("Value").MakeGenericMethod(property.PropertyType);
- var val = method.Invoke(jObject, new object[] { property.Name.ToLower() });
- property.SetValue(value, val);
- }
- }
- }
- return value;
- }
- public override bool CanConvert(Type objectType)
- {
- // TODO.
- return true;
- }
- // TODO.
- public override bool CanRead => true;
- public override bool CanWrite => true;
- }
- public class Foo
- {
- public int Y { get; set; }
- public int Z { get; set; }
- }
- public class Bar
- {
- public string X { get; set; }
- public Foo Foo { get; set; }
- }
- class Program
- {
- static void Main(string[] args)
- {
- var jsonSettings = new JsonSerializerSettings
- {
- Converters = new List<JsonConverter> { new FlatJsonConverter() }
- };
- var obj = JsonConvert.DeserializeObject<Bar>("{\"x\": 1, \"foo\": {\"y\": 2, \"z\": 3}}",
- new JsonSerializerSettings { Converters = new List<JsonConverter> { new FlatJsonConverter() } });
- Console.WriteLine(JsonConvert.SerializeObject(obj));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement