JSON 帮助类

/// <summary>
    /// 用于构建属性值的回调
    /// </summary>
    /// <param name="property"></param>
    public delegate void SetPropertiesDelegate(JsonObject property);

    /// <summary>
    /// JsonObject属性值类型
    /// </summary>
    public enum JsonPropertyType
    {
        String,
        Object,
        Array,
        Number,
        Bool,
        Null
    }

    /// <summary>
    /// JSON通用对象
    /// </summary>
    public class JsonObject
    {
        private Dictionary<String, JsonProperty> mProperty;

        /// <summary>
        /// 创建一个JSON对象
        /// </summary>
        public JsonObject()
        {
            this.mProperty = null;
        }

        /// <summary>
        /// 通过字符串构造一个JSON对象
        /// </summary>
        /// <param name="jsonString"></param>
        public JsonObject(String jsonString)
        {
            this.Parse(ref jsonString);
        }

        /// <summary>
        /// 通过回调函数构造一个JSON对象
        /// </summary>
        /// <param name="callback"></param>
        public JsonObject(SetPropertiesDelegate callback)
        {
            if (callback != null)
            {
                callback(this);
            }
        }

        /// <summary>
        /// Json字符串解析
        /// </summary>
        /// <param name="jsonString"></param>
        private void Parse(ref String jsonString)
        {
            int len = jsonString.Length;
            if (String.IsNullOrEmpty(jsonString) || jsonString.Substring(0, 1) != "{" || jsonString.Substring(jsonString.Length - 1, 1) != "}")
            {
                throw new ArgumentException("传入文本不符合Json格式!" + jsonString);
            }
            Stack<Char> stack = new Stack<char>();
            Stack<Char> stackType = new Stack<char>();
            Stack<char> stackStrValue = new Stack<char>();      //Value中的特殊字符需要保留
            StringBuilder sb = new StringBuilder();
            Char cur;
            bool isValue = false;
            JsonProperty last = null;
            for (int i = 1; i <= len - 2; i++)
            {
                cur = jsonString[i];
                if (cur == '}')
                {
                    ;
                }
                if (cur == ' ' && stack.Count == 0 && stackStrValue.Count == 0)
                {
                    ;
                }
                else if ((cur == '\'' || cur == '\"') && stack.Count == 0 && !isValue)
                {
                    sb.Length = 0;
                    stack.Push(cur);
                }
                else if ((cur == '\'' || cur == '\"') && stack.Count > 0 && stack.Peek() == cur && !isValue)
                {
                    stack.Pop();
                }
                else if ((cur == '\'' || cur == '\"') && isValue && stackStrValue.Count == 0)
                {

                    sb.Append(cur);
                    stackStrValue.Push(cur);

                }
                else if ((cur == '\'' || cur == '\"') && isValue && stackStrValue.Count > 0 && stackStrValue.Peek() == cur)
                {
                    sb.Append(cur);
                    stackStrValue.Pop();
                }
                else if ((cur == '[' || cur == '{') && stack.Count == 0)
                {
                    stackType.Push(cur == '[' ? ']' : '}');
                    sb.Append(cur);
                }
                else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Peek() == cur)
                {
                    stackType.Pop();
                    sb.Append(cur);
                }
                else if (cur == ':' && stack.Count == 0 && stackType.Count == 0 && !isValue)
                {
                    last = new JsonProperty();
                    this[sb.ToString()] = last;
                    isValue = true;
                    sb.Length = 0;
                }
                else if (cur == ',' && stack.Count == 0 && stackType.Count == 0 && stackStrValue.Count == 0)
                {
                    if (last != null)
                    {

                        String temp = sb.ToString();
                        last.Parse(ref temp);
                    }
                    isValue = false;
                    sb.Length = 0;
                }
                else
                {
                    sb.Append(cur);
                }
            }
            if (sb.Length > 0 && last != null && last.Type == JsonPropertyType.Null)
            {
                String temp = sb.ToString();
                last.Parse(ref temp);
            }
        }

        /// <summary>
        /// 获取指定名称的属性
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public JsonProperty this[String propertyName]
        {
            get
            {
                JsonProperty result = null;
                if (this.mProperty != null && this.mProperty.ContainsKey(propertyName))
                {
                    result = this.mProperty[propertyName];
                }
                return result;
            }
            set
            {
                if (this.mProperty == null)
                {
                    this.mProperty = new Dictionary<string, JsonProperty>(StringComparer.OrdinalIgnoreCase);
                }
                if (this.mProperty.ContainsKey(propertyName))
                {
                    this.mProperty[propertyName] = value;
                }
                else
                {
                    this.mProperty.Add(propertyName, value);
                }
            }
        }

        /// <summary>
        /// 通过此泛型函数可直接获取指定类型属性的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public virtual T Properties<T>(String propertyName) where T : class
        {
            JsonProperty p = this[propertyName];
            if (p != null)
            {
                return p.GetValue<T>();
            }
            return default(T);
        }

        /// <summary>
        /// 获取属性名称列表
        /// </summary>
        /// <returns></returns>
        public String[] GetPropertyNames()
        {
            if (this.mProperty == null)
                return null;
            String[] keys = null;
            if (this.mProperty.Count > 0)
            {
                keys = new String[this.mProperty.Count];
                this.mProperty.Keys.CopyTo(keys, 0);
            }
            return keys;
        }

        /// <summary>
        /// 移除一个属性
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public JsonProperty RemoveProperty(String propertyName)
        {
            if (this.mProperty != null && this.mProperty.ContainsKey(propertyName))
            {
                JsonProperty p = this.mProperty[propertyName];
                this.mProperty.Remove(propertyName);
                return p;
            }
            return null;
        }

        /// <summary>
        /// 是否为空对象
        /// </summary>
        /// <returns></returns>
        public bool IsNull()
        {
            return this.mProperty == null;
        }

        /// <summary>
        /// 转换成字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.ToString("");
        }

        /// <summary>
        /// 指定格式表达式,转换成字符串
        /// </summary>
        /// <param name="format">格式化字符串</param>
        /// <returns></returns>
        public virtual string ToString(String format)
        {
            if (this.IsNull())
            {
                return "{}";
            }
            StringBuilder sb = new StringBuilder();
            foreach (String key in this.mProperty.Keys)
            {
                sb.Append(",");
                //sb.Append(key).Append(": ");
                sb.Append("\"" + key + "\"").Append(":");
                sb.Append(this.mProperty[key].ToString(format));

            }
            if (this.mProperty.Count > 0)
            {
                sb.Remove(0, 1);
            }
            sb.Insert(0, "{");
            sb.Append("}");
            return sb.ToString();
        }
    }

    /// <summary>
    /// JSON对象属性
    /// </summary>
    public class JsonProperty
    {
        private JsonPropertyType mType;
        private String mValue;
        private JsonObject mObject;
        private List<JsonProperty> mList;
        private bool mBool;
        private double mNumber;

        /// <summary>
        /// 创建一个空的JSON对象属性
        /// </summary>
        public JsonProperty()
        {
            this.mType = JsonPropertyType.Null;
            this.mValue = null;
            this.mObject = null;
            this.mList = null;
        }

        /// <summary>
        /// 创建一个JSON对象属性
        /// </summary>
        /// <param name="value"></param>
        public JsonProperty(Object value)
        {
            this.SetValue(value);
        }

        /// <summary>
        /// 通过字符串构造一个JSON对象属性
        /// </summary>
        /// <param name="jsonString"></param>
        public JsonProperty(String jsonString)
        {
            this.Parse(ref jsonString);
        }


        /// <summary>
        /// Json字符串解析
        /// </summary>
        /// <param name="jsonString"></param>
        public void Parse(ref String jsonString)
        {
            if (String.IsNullOrEmpty(jsonString))
            {
                this.SetValue(null);
            }
            else
            {
                string first = jsonString.Substring(0, 1);
                string last = jsonString.Substring(jsonString.Length - 1, 1);
                //集合
                if (first == "[" && last == "]")
                {
                    this.SetValue(this.ParseArray(ref jsonString));
                }
                //JSON 对象
                else if (first == "{" && last == "}")
                {
                    this.SetValue(this.ParseObject(ref jsonString));
                }
                //字符串类型
                else if ((first == "'" || first == "\"") && first == last)
                {
                    this.SetValue(this.ParseString(ref jsonString));
                }
                //Bool类型
                else if (jsonString == "true" || jsonString == "false")
                {
                    this.SetValue(jsonString == "true" ? true : false);
                }
                //空类型
                else if (jsonString == "null")
                {
                    this.SetValue(null);
                }
                else
                {
                    double d = 0;
                    //数值类型
                    if (double.TryParse(jsonString, out d))
                    {
                        this.SetValue(d);
                    }
                    else
                    {
                        this.SetValue(jsonString);
                    }
                }
            }
        }

        /// <summary>
        /// Json Array解析
        /// </summary>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        private List<JsonProperty> ParseArray(ref String jsonString)
        {
            List<JsonProperty> list = new List<JsonProperty>();
            int len = jsonString.Length;
            StringBuilder sb = new StringBuilder();
            Stack<Char> stack = new Stack<Char>();
            Stack<Char> stackType = new Stack<Char>();
            Stack<Char> stackStrValue = new Stack<Char>();  //Value中的特殊字符需要保留
            bool conver = false;
            Char cur;
            for (int i = 1; i <= len - 2; i++)
            {
                cur = jsonString[i];
                if (Char.IsWhiteSpace(cur) && stack.Count == 0 && stackStrValue.Count == 0)
                {
                    ;
                }
                else if ((cur == '\'' || cur == '\"') && stack.Count == 0 && stackType.Count == 0)
                {
                    sb.Length = 0;
                    sb.Append(cur);
                    stack.Push(cur);
                }
                else if (cur == '\\' && stack.Count > 0 && !conver)
                {
                    sb.Append(cur);
                    conver = true;
                }
                else if (conver == true)
                {
                    conver = false;

                    if (cur == 'u')
                    {
                        sb.Append(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
                        i += 4;
                    }
                    else
                    {
                        sb.Append(cur);
                    }
                }
                else if ((cur == '\'' || cur == '\"') && stack.Count > 0 && stack.Peek() == cur && stackType.Count == 0)
                {
                    sb.Append(cur);
                    list.Add(new JsonProperty(sb.ToString()));
                    stack.Pop();
                }
                else if ((cur == '\'' || cur == '\"') && stackStrValue.Count == 0)
                {
                    sb.Append(cur);
                    stackStrValue.Push(cur);
                }
                else if ((cur == '\'' || cur == '\"') && stackStrValue.Count > 0 && stackStrValue.Peek() == cur)
                {
                    sb.Append(cur);
                    stackStrValue.Pop();
                }
                else if ((cur == '[' || cur == '{') && stack.Count == 0)
                {
                    if (stackType.Count == 0)
                    {
                        sb.Length = 0;
                    }
                    sb.Append(cur);
                    stackType.Push((cur == '[' ? ']' : '}'));
                }
                else if ((cur == ']' || cur == '}') && stack.Count == 0 && stackType.Count > 0 && stackType.Peek() == cur)
                {
                    sb.Append(cur);
                    stackType.Pop();
                    if (stackType.Count == 0)
                    {
                        list.Add(new JsonProperty(sb.ToString()));
                        sb.Length = 0;
                    }
                }
                else if (cur == ',' && stack.Count == 0 && stackType.Count == 0)
                {
                    if (sb.Length > 0)
                    {
                        list.Add(new JsonProperty(sb.ToString()));
                        sb.Length = 0;
                    }
                }
                else
                {
                    sb.Append(cur);
                }
            }
            if (stack.Count > 0 || stackType.Count > 0)
            {
                list.Clear();
                throw new ArgumentException("无法解析Json Array对象!");
            }
            else if (sb.Length > 0)
            {
                list.Add(new JsonProperty(sb.ToString()));
            }
            return list;
        }


        /// <summary>
        /// Json String解析
        /// </summary>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        private String ParseString(ref String jsonString)
        {
            int len = jsonString.Length;
            StringBuilder sb = new StringBuilder();
            bool conver = false;
            Char cur;
            for (int i = 1; i <= len - 2; i++)
            {
                cur = jsonString[i];
                if (cur == '\\' && !conver)
                {
                    conver = true;
                }
                else if (conver == true)
                {
                    conver = false;
                    if (cur == '\\' || cur == '\"' || cur == '\'' || cur == '/')
                    {
                        sb.Append(cur);
                    }
                    else
                    {
                        if (cur == 'u')
                        {
                            String temp = new String(new char[] { cur, jsonString[i + 1], jsonString[i + 2], jsonString[i + 3] });
                            sb.Append((char)Convert.ToInt32(temp, 16));
                            i += 4;
                        }
                        else
                        {
                            switch (cur)
                            {
                                case 'b':
                                    sb.Append('\b');
                                    break;
                                case 'f':
                                    sb.Append('\f');
                                    break;
                                case 'n':
                                    sb.Append('\n');
                                    break;
                                case 'r':
                                    sb.Append('\r');
                                    break;
                                case 't':
                                    sb.Append('\t');
                                    break;
                            }
                        }
                    }
                }
                else
                {
                    sb.Append(cur);
                }
            }
            return sb.ToString();
        }

        /// <summary>
        /// Json Object解析
        /// </summary>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        private JsonObject ParseObject(ref String jsonString)
        {
            return new JsonObject(jsonString);
        }

        /// <summary>
        /// 定义一个索引器,如果属性是非数组的,返回本身
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public JsonProperty this[int index]
        {
            get
            {
                JsonProperty r = null;
                if (this.mType == JsonPropertyType.Array)
                {
                    if (this.mList != null && (this.mList.Count - 1) >= index)
                    {
                        r = this.mList[index];
                    }
                }
                else if (index == 0)
                {
                    return this;
                }
                return r;
            }
        }

        /// <summary>
        /// 提供一个字符串索引,简化对Object属性的访问
        /// </summary>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public JsonProperty this[String propertyName]
        {
            get
            {
                if (this.mType == JsonPropertyType.Object)
                {
                    return this.mObject[propertyName];
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (this.mType == JsonPropertyType.Object)
                {
                    this.mObject[propertyName] = value;
                }
                else
                {
                    throw new NotSupportedException("Json属性不是对象类型!");
                }
            }
        }

        /// <summary>
        /// JsonObject值
        /// </summary>
        public JsonObject Object
        {
            get
            {
                if (this.mType == JsonPropertyType.Object)
                    return this.mObject;
                return null;
            }
        }

        /// <summary>
        /// 字符串值
        /// </summary>
        public String Value
        {
            get
            {
                if (this.mType == JsonPropertyType.String)
                {
                    return this.mValue;
                }
                else if (this.mType == JsonPropertyType.Number)
                {
                    return this.mNumber.ToString();
                }
                return null;
            }
        }

        /// <summary>
        /// 对于集合类型,添加一个元素
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public JsonProperty Add(Object value)
        {
            if (this.mType != JsonPropertyType.Null && this.mType != JsonPropertyType.Array)
            {
                throw new NotSupportedException("Json属性不是Array类型,无法添加元素!");
            }
            if (this.mList == null)
            {
                this.mList = new List<JsonProperty>();
            }
            JsonProperty jp = new JsonProperty(value);
            this.mList.Add(jp);
            this.mType = JsonPropertyType.Array;
            return jp;
        }

        /// <summary>
        /// Array值,如果属性是非数组的,则封装成只有一个元素的数组
        /// </summary>
        public List<JsonProperty> Items
        {
            get
            {
                if (this.mType == JsonPropertyType.Array)
                {
                    return this.mList;
                }
                else
                {
                    List<JsonProperty> list = new List<JsonProperty>();
                    list.Add(this);
                    return list;
                }
            }
        }

        /// <summary>
        /// 数值
        /// </summary>
        public double Number
        {
            get
            {
                if (this.mType == JsonPropertyType.Number)
                {
                    return this.mNumber;
                }
                else
                {
                    return double.NaN;
                }
            }
        }

        /// <summary>
        /// 清空属性值,重置为默认值
        /// </summary>
        public void Clear()
        {
            this.mType = JsonPropertyType.Null;
            this.mValue = String.Empty;
            this.mObject = null;
            if (this.mList != null)
            {
                this.mList.Clear();
                this.mList = null;
            }
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <returns></returns>
        public Object GetValue()
        {
            if (this.mType == JsonPropertyType.String)
            {
                return this.mValue;
            }
            if (this.mType == JsonPropertyType.Object)
            {
                return this.mObject;
            }
            if (this.mType == JsonPropertyType.Array)
            {
                return this.mList;
            }
            if (this.mType == JsonPropertyType.Bool)
            {
                return this.mBool;
            }
            if (this.mType == JsonPropertyType.Number)
            {
                return this.mNumber;
            }
            return null;
        }

        /// <summary>
        /// 获取指定类型的属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public virtual T GetValue<T>() where T : class
        {
            return (GetValue() as T);
        }

        /// <summary>
        /// 设置属性的值
        /// </summary>
        /// <param name="value"></param>
        public virtual void SetValue(Object value)
        {
            if (value is String)
            {
                this.mType = JsonPropertyType.String;
                this.mValue = (String)value;
            }
            else if (value is List<JsonProperty>)
            {
                this.mList = ((List<JsonProperty>)value);
                this.mType = JsonPropertyType.Array;
            }
            else if (value is JsonObject)
            {
                this.mObject = (JsonObject)value;
                this.mType = JsonPropertyType.Object;
            }
            else if (value is bool)
            {
                this.mBool = (bool)value;
                this.mType = JsonPropertyType.Bool;
            }
            else if (value == null)
            {
                this.mType = JsonPropertyType.Null;
            }
            else
            {
                double d = 0;
                if (double.TryParse(value.ToString(), out d))
                {
                    this.mNumber = d;
                    this.mType = JsonPropertyType.Number;
                }
                else
                {
                    throw new ArgumentException("错误的参数类型!");
                }
            }
        }

        /// <summary>
        /// 对于集合类型,返回元素的数目
        /// </summary>
        public virtual int Count
        {
            get
            {
                int c = 0;
                if (this.mType == JsonPropertyType.Array)
                {
                    if (this.mList != null)
                    {
                        c = this.mList.Count;
                    }
                }
                else
                {
                    c = 1;
                }
                return c;
            }
        }

        /// <summary>
        /// 返回属性值类型
        /// </summary>
        public JsonPropertyType Type
        {
            get { return this.mType; }
        }

        /// <summary>
        /// 转换成字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.ToString("");
        }

        /// <summary>
        /// 指定格式表达式转换成字符串
        /// </summary>
        /// <param name="format"></param>
        /// <returns></returns>
        public virtual string ToString(String format)
        {
            StringBuilder sb = new StringBuilder();
            if (this.mType == JsonPropertyType.String)
            {
                sb.Append("\"").Append(this.mValue).Append("\"");
                return sb.ToString();
            }
            else if (this.mType == JsonPropertyType.Bool)
            {
                return this.mBool ? "true" : "false";
            }
            else if (this.mType == JsonPropertyType.Number)
            {
                return this.mNumber.ToString();
            }
            else if (this.mType == JsonPropertyType.Null)
            {
                return "null";
            }
            else if (this.mType == JsonPropertyType.Object)
            {
                return this.mObject.ToString();
            }
            else
            {
                if (this.mList == null || this.mList.Count == 0)
                {
                    sb.Append("[]");
                }
                else
                {
                    sb.Append("[");
                    if (this.mList.Count > 0)
                    {
                        foreach (JsonProperty p in this.mList)
                        {
                            sb.Append(p.ToString());
                            sb.Append(", ");
                        }
                        sb.Length -= 2;
                    }
                    sb.Append("]");
                }
                return sb.ToString();
            }
        }
    }


 

发布了41 篇原创文章 · 获赞 9 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jian200801/article/details/12004331