随笔 - 74,  文章 - 1,  评论 - 1,  阅读 - 45011
复制代码
   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);
        }
    }
复制代码

 

posted on   不知勿言  阅读(221)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2021-05-24 汉字表示范围

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示