专栏首页魂祭心原 ObjectToJson实现

原 ObjectToJson实现

特性标记:

    [System.AttributeUsage(System.AttributeTargets.Property)]
    class UseForJsonAttribute : Attribute
    {
        public Boolean IsUse { get; set; }
        public UseForJsonAttribute(Boolean isUse)
        {
            IsUse = isUse;
        }
    }

代码:

    public class ObjToJson<T>
    {
        //为null时返回
        private const string undifined = "\"undefined\"";
        StringBuilder jsonBuilder = new StringBuilder();
        public ObjToJson()
        {
            if (typeof(T).IsGenericType)
            { throw new Exception("暂不支持泛型"); }
        }
        public string ToJson(T instance)
        {
            if (instance == null) return undifined;
            MakeJson(instance);
            return jsonBuilder.ToString();
        }
        private void MakeJson(Object instance)
        {
            //区分数组类型和普通类
            if (instance is Array)
            {
                ArrayToJson(instance);
            }
            else {
                EntityToJson(instance);
            }
        }
        private void ArrayToJson(Object instance)
        {
            jsonBuilder.Append("[");
            Array obj = (instance as Array);
            //逐个循环调用makjson
            for (int i = 0; i < obj.Length; i++)
            {
                if (obj.GetValue(i) == null)
                    jsonBuilder.Append(undifined);
                else
                    MakeJson(obj.GetValue(i));
                jsonBuilder.Append(",");
            }
            if (jsonBuilder[jsonBuilder.Length - 1] == ',')
            {
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            }
            jsonBuilder.Append("]");
        }
        private void EntityToJson(Object instance)
        {
            jsonBuilder.Append("{");
            PropertyInfo[] pInfos = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
            foreach (PropertyInfo pInfo in pInfos)
            {
                //判断该成员是否序列
                if (IsUseProperty(pInfo))
                {
                    //加入key
                    jsonBuilder.Append("\"");
                    TransformChar(pInfo.Name);
                    jsonBuilder.Append("\":");
                    //加入value
                    object value = pInfo.GetValue(instance);
                    if (pInfo.PropertyType.IsValueType)
                    {
                        //值类型
                        TransformChar(value.ToString());
                        jsonBuilder.Append(',');
                    }            
                    else if (pInfo.PropertyType.ToString() == "System.String")
                    {
                        //字符类型
                        jsonBuilder.Append("\"");
                        if (value == null)
                            jsonBuilder.Append(undifined);
                        else
                            TransformChar(value.ToString());
                        jsonBuilder.Append("\",");
                    }
                    else {
                        //引用类型
                        if (value == null)
                            jsonBuilder.Append(undifined);
                        else
                            MakeJson(value);
                        jsonBuilder.Append(',');
                    }
                }
            }
            if (jsonBuilder[jsonBuilder.Length - 1] == ',')
            {
                jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            }
            jsonBuilder.Append("}");
        }
        private bool IsUseProperty(PropertyInfo pInfo)
        {
            UseForJsonAttribute ufa = pInfo.GetCustomAttribute<UseForJsonAttribute>();
            if (ufa != null && ufa.IsUse == true)
            { return true; }
            return false;
        }
        private void TransformChar(string aString)
        {
            for (int i = 0; i < aString.Length; ++i)
            {
                switch (aString[i])
                {
                    case '\\':
                        jsonBuilder.Append("\\\\");
                        break;

                    case '/':
                        jsonBuilder.Append("\\/");
                        break;

                    case '"':
                        jsonBuilder.Append("\\\"");
                        break;

                    case '\t':
                        jsonBuilder.Append("\\t");
                        break;
                    case '\f':
                        jsonBuilder.Append("\\f");
                        break;
                    case '\b':
                        jsonBuilder.Append("\\b");
                        break;
                    case '\n':
                        jsonBuilder.Append("\\n");
                        break;
                    case '\r':
                        jsonBuilder.Append("\\r");
                        break;
                    default:
                        {
                            jsonBuilder.Append(aString[i]);
                            break;
                        }

                }
            }
        }
    }

测试类:

    public class Class
    {
        [UseForJsonAttribute(true)]
        public int RoomID { get; set; }
        [UseForJsonAttribute(true)]
        public string description { get; set; }
        [UseForJsonAttribute(true)]
        public Person[] students { get; set; }
        [UseForJsonAttribute(true)]
        public Person teacher { get; set; }
    }
    public class Person
    {
        public Person() { }
        [UseForJsonAttribute(true)]
        public String Name { get; set; }
        [UseForJsonAttribute(true)]
        public Address Address { get; set; }
        [UseForJsonAttribute(true)]
        public int Age { get; set; }
    }
public class Address {
        [UseForJsonAttribute(true)]
        public string Country { get; set; }
        [UseForJsonAttribute(true)]
        public string Privince { get; set; }

        public int Num { get; set; }
}

json生成测试

 Address address1 = new Address();
            address1.Country = "china";
            address1.Privince = "shanghai";

            Address address2 = new Address();
            address2.Country = "china";
            address2.Privince = "beijjing";

            Address address3 = new Address();
            address3.Country = "china";
            address3.Privince = "anhui";

            Person person1 = new Person();
            person1.Name = "jake";
            person1.Age = 22;
            person1.Address = address1;

            Person person2 = new Person();
            person2.Name = "jake";
            person2.Age = 22;
            person2.Address = address1;

            Person person3 = new Person();
            person3.Name = "jake";
            person3.Age = 22;
            person3.Address = address1;

            Class class1 = new Class();
            class1.RoomID = 12;
            class1.teacher = person1;

            class1.students = new Person[5];
            class1.students[0] = person2;
            class1.students[1] = null;
            class1.students[2] = person3;
            class1.students[3] = null;
            class1.students[4] = person3;
            class1.description = "\\\'\".,sadwqqw\t\req\\we\n{}[]";
            ObjToJson<Class> json = new ObjToJson<Class>();
            this.textBox1.Text = json.ToJson(class1);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 原 数据字典+匿名委托模拟switch/c

    魂祭心
  • 原 二叉树 非递归 层序、前序、中序、后序

    魂祭心
  • 原 js页面传值参数打包类

    魂祭心
  • 漏洞复现 | WordPress 4.2.0-4.5.1 flashmediaelement.swf 反射型 XSS

    首先来看存在漏洞的输出, 99%的Flash XSS都是由于ExternalInterface.call函数的参数注入导致的, 当然本次也不例外. 拿到源码之后...

    TeamsSix
  • 虐面试官系列Lifecyele 篇 -(1)基础知识

    又是很久很久没写文章了,最近打算写下Android的又一基础知识: Android 官方架构组件系列。打算把相关的知识点都整理写下,所以本系列的主体为Lifec...

    青蛙要fly
  • Android Room 持久化库

    佛系编码
  • Java开发中的23种设计模式详解

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

    用户5640963
  • java编程思想第四版第十一章总结

      List<Apple> list = new ArrayList<Apple>();

    用户7798898
  • 浅谈lambda表达式<最通俗易懂的讲解>

    lambda体中调用方法的参数列表和返回值类型,要和函数式接口中抽象方法的参数列表和返回值类型保持一致。

    Java编程指南
  • Java开发中的23种设计模式详解(转)

                                      ——可复用面向对象软件的基础

    肖哥哥

扫码关注云+社区

领取腾讯云代金券