public class ObjectConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { return true; } public override bool CanWrite { get { var type = typeof(T); return type.IsClass; } } public override bool CanRead { get { return true; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException("Unnecessary because CanRead is false.The type will skip the converter."); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { JObject containerObj = new JObject(); var properties = value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); string enumPropStrName = string.Empty; List<string> enumPropNames = new List<string>(); foreach (var prop in properties) { var val = prop.GetValue(value); if (prop.PropertyType.IsEnum || (prop.PropertyType.IsGenericType && prop.PropertyType.GenericTypeArguments[0].IsEnum)) { if (properties.Count(x => string.Compare(x.Name, (prop.Name + "Str"), true) == 0) > 0) { enumPropStrName = prop.Name + "Str"; var first = properties.First(x => string.Compare(x.Name, enumPropStrName, true) == 0); if (containerObj.Properties().Count(x => x.Name == enumPropStrName) <= 0) { containerObj.Add(enumPropStrName, val.GetEnumDescription()); } else { containerObj[enumPropStrName] = val.GetEnumDescription(); } enumPropNames.Add(enumPropStrName); } else if (properties.Count(x => string.Compare(x.Name, (prop.Name + "Desc"), true) == 0) > 0) { enumPropStrName = prop.Name + "Desc"; var first = properties.First(x => string.Compare(x.Name, enumPropStrName, true) == 0); if (containerObj.Properties().Count(x => x.Name == enumPropStrName) <= 0) { containerObj.Add(enumPropStrName, val.GetEnumDescription()); } else { containerObj[enumPropStrName] = val.GetEnumDescription(); } enumPropNames.Add(enumPropStrName); } } else if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string)) { JToken itemObj = null; if (val.GetType().GetInterfaces()?.Count(x => x == typeof(IEnumerable)) > 0) { itemObj = JArray.FromObject(val); } else { itemObj = JObject.FromObject(val); } if (containerObj.Properties().Count(x => x.Name == prop.Name) <= 0) { containerObj.Add(prop.Name, itemObj); } else { containerObj[prop.Name] = itemObj; } } else { var attr = prop.GetCustomAttribute<PropertySerilizerAttribute>(); if (attr != null) { val = attr.Convert(val, value); } JToken jVal = null; if (val != null) { jVal = JToken.FromObject(val); } if (!enumPropNames.Contains(prop.Name)) { if (containerObj.Properties().Count(x => x.Name == prop.Name) <= 0) { containerObj.Add(prop.Name, jVal); } else { containerObj[prop.Name] = jVal; } } } } containerObj.WriteTo(writer); } } public abstract class PropertyConverter { public abstract object Convert(object source, object obj); } public class DatePropertyConverter : PropertyConverter { public override object Convert(object source, object obj) { if (source != null && (source.GetType() == typeof(DateTime) || source.GetType() == typeof(DateTime?))) { return ((DateTime)source).ToString("yyyy-MM-dd"); } return null; } } public class DateTimePropertyConverter : PropertyConverter { public override object Convert(object source, object obj) { if (source != null && (source.GetType() == typeof(DateTime) || source.GetType() == typeof(DateTime?))) { return ((DateTime)source).ToString("yyyy-MM-dd HH:mm:ss"); } return null; } } /// <summary> /// 属性序列化 /// </summary> [AttributeUsage(AttributeTargets.Property)] public class PropertySerilizerAttribute : Attribute { protected PropertyConverter Converter { get; set; } public PropertySerilizerAttribute(Type type) { if (type == typeof(PropertyConverter) || type?.BaseType == typeof(PropertyConverter)) { Converter = (PropertyConverter)Activator.CreateInstance(type); } } public object Convert(object source, object obj) { return Converter?.Convert(source, obj); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2021-05-24 汉字表示范围