NewLife/X

开始构建Json序列化框架,编译通过,未完成
nnhy 编写于 2016-04-12 18:12:02
共计: 修改9个文件,增加1075行、删除289行。
修改 +6 -0
修改 +42 -280
增加 +309 -0
增加 +197 -0
增加 +124 -0
增加 +281 -0
增加 +10 -0
增加 +96 -0
修改 +10 -9
修改 +6 -0
diff --git a/NewLife.Core/NewLife.Core.csproj b/NewLife.Core/NewLife.Core.csproj
index d840da7..a441e3d 100644
--- a/NewLife.Core/NewLife.Core.csproj
+++ b/NewLife.Core/NewLife.Core.csproj
@@ -164,6 +164,12 @@
     <Compile Include="Reflection\AttributeX.cs" />
     <Compile Include="Reflection\快速反射\ConstructorInfoX.cs" />
     <Compile Include="Reflection\EmitHelper.cs" />
+    <Compile Include="Serialization\Json\IJsonHost.cs" />
+    <Compile Include="Serialization\Json\Json.cs" />
+    <Compile Include="Serialization\Json\JsonComposite.cs" />
+    <Compile Include="Serialization\Json\JsonDictionary.cs" />
+    <Compile Include="Serialization\Json\JsonGeneral.cs" />
+    <Compile Include="Serialization\Json\JsonArray.cs" />
     <Compile Include="Serialization\Json\IJson.cs" />
     <Compile Include="Serialization\Protocol.cs">
       <SubType>Code</SubType>
修改 +42 -280
diff --git a/NewLife.Core/Serialization/Json/IJson.cs b/NewLife.Core/Serialization/Json/IJson.cs
index 6e4ae40..c64efc7 100644
--- a/NewLife.Core/Serialization/Json/IJson.cs
+++ b/NewLife.Core/Serialization/Json/IJson.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Reflection;
 using System.Text;
 using System.Web.Script.Serialization;
@@ -8,302 +9,63 @@ using NewLife.Reflection;
 
 namespace NewLife.Serialization
 {
-    /// <summary>Json序列化接口</summary>
-    public interface IJson
+    /// <summary>IJson序列化接口</summary>
+    public interface IJson : IFormatterX
     {
-        /// <summary>写入对象,得到Json字符串</summary>
-        /// <param name="value"></param>
-        /// <param name="indented">是否缩进</param>
-        /// <returns></returns>
-        String Write(Object value, Boolean indented = false);
-
-        /// <summary>从Json字符串中读取对象</summary>
-        /// <param name="json"></param>
-        /// <param name="type"></param>
-        /// <returns></returns>
-        Object Read(String json, Type type);
-    }
-
-    /// <summary>Json助手</summary>
-    public static class JsonHelper
-    {
-        /// <summary>默认实现</summary>
-        public static IJson Default { get; set; }
+        #region 属性
+        /// <summary>是否缩进</summary>
+        Boolean Indented { get; set; }
 
-        static JsonHelper()
-        {
-            if (JsonNet.Support())
-                Default = new JsonNet();
-            else
-                Default = new JsonDefault();
-        }
+        /// <summary>处理器列表</summary>
+        IList<IJsonHandler> Handlers { get; }
+        #endregion
 
-        /// <summary>写入对象,得到Json字符串</summary>
+        #region 写入
+        /// <summary>写入字符串</summary>
         /// <param name="value"></param>
-        /// <param name="indented">是否缩进</param>
-        /// <returns></returns>
-        public static String ToJson(this Object value, Boolean indented = false)
-        {
-            return Default.Write(value, indented);
-        }
-
-        /// <summary>从Json字符串中读取对象</summary>
-        /// <param name="json"></param>
-        /// <param name="type"></param>
-        /// <returns></returns>
-        public static Object ToJsonEntity(this String json, Type type)
-        {
-            return Default.Read(json, type);
-        }
-
-        /// <summary>从Json字符串中读取对象</summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="json"></param>
-        /// <returns></returns>
-        public static T ToJsonEntity<T>(this String json)
-        {
-            return (T)Default.Read(json, typeof(T));
-        }
-    }
-
-    class JsonDefault : IJson
-    {
-        //static JsonDefault()
-        //{
-        //    // 用XmlIgnore特性作为忽略属性的方法
-        //    var src = typeof(JavaScriptSerializer).GetMethodEx("CheckScriptIgnoreAttribute");
-        //    var dst = typeof(JsonDefault).GetMethodEx("CheckScriptIgnoreAttribute");
-        //    if (src != null && dst != null)
-        //    {
-        //        //new JavaScriptSerializer().Invoke(src, src);
-        //        //new JsonDefault().CheckScriptIgnoreAttribute(dst);
-        //        ApiHook.ReplaceMethod(src, dst);
-        //    }
-        //}
-
-        private bool CheckScriptIgnoreAttribute(MemberInfo memberInfo)
-        {
-            if (memberInfo.IsDefined(typeof(ScriptIgnoreAttribute), true)) return true;
-            if (memberInfo.IsDefined(typeof(XmlIgnoreAttribute), true)) return true;
-
-            return false;
-        }
-
-        #region IJson 成员
-        public String Write(Object value, Boolean indented)
-        {
-            var json = new JavaScriptSerializer().Serialize(value);
-            //if (indented) json = Process(json);
-            if (indented) json = FormatOutput(json);
-
-            return json;
-        }
-
-        public Object Read(String json, Type type)
-        {
-            // 如果有必要,可以实现JavaScriptTypeResolver,然后借助Type.GetTypeEx得到更强的反射类型能力
-            return new JavaScriptSerializer().Deserialize(json, type);
-        }
+        void Write(String value);
 
-        //static String Process(String inputText)
-        //{
-        //    bool escaped = false;
-        //    bool inquotes = false;
-        //    int column = 0;
-        //    int indentation = 0;
-        //    var indentations = new Stack<int>();
-        //    int TABBING = 8;
-        //    var sb = new StringBuilder();
-        //    foreach (char x in inputText)
-        //    {
-        //        sb.Append(x);
-        //        column++;
-        //        if (escaped)
-        //        {
-        //            escaped = false;
-        //        }
-        //        else
-        //        {
-        //            if (x == '\\')
-        //            {
-        //                escaped = true;
-        //            }
-        //            else if (x == '\"')
-        //            {
-        //                inquotes = !inquotes;
-        //            }
-        //            else if (!inquotes)
-        //            {
-        //                if (x == ',')
-        //                {
-        //                    // if we see a comma, go to next line, and indent to the same depth
-        //                    sb.Append("\r\n");
-        //                    column = 0;
-        //                    for (int i = 0; i < indentation; i++)
-        //                    {
-        //                        sb.Append(" ");
-        //                        column++;
-        //                    }
-        //                }
-        //                else if (x == '[' || x == '{')
-        //                {
-        //                    // if we open a bracket or brace, indent further (push on stack)
-        //                    indentations.Push(indentation);
-        //                    indentation = column;
-        //                }
-        //                else if (x == ']' || x == '}')
-        //                {
-        //                    // if we close a bracket or brace, undo one level of indent (pop)
-        //                    indentation = indentations.Pop();
-        //                }
-        //                else if (x == ':')
-        //                {
-        //                    // if we see a colon, add spaces until we get to the next
-        //                    // tab stop, but without using tab characters!
-        //                    while ((column % TABBING) != 0)
-        //                    {
-        //                        sb.Append(' ');
-        //                        column++;
-        //                    }
-        //                }
-        //            }
-        //        }
-        //    }
-        //    return sb.ToString();
-        //}
-
-        static String FormatOutput(String json)
-        {
-            var sb = new StringBuilder();
-
-            bool escaping = false;
-            bool inQuotes = false;
-            int indentation = 0;
+        void Write(StringBuilder sb, Object value);
+        #endregion
 
-            foreach (char ch in json)
-            {
-                if (escaping)
-                {
-                    escaping = false;
-                    sb.Append(ch);
-                }
-                else
-                {
-                    if (ch == '\\')
-                    {
-                        escaping = true;
-                        sb.Append(ch);
-                    }
-                    else if (ch == '\"')
-                    {
-                        inQuotes = !inQuotes;
-                        sb.Append(ch);
-                    }
-                    else if (!inQuotes)
-                    {
-                        if (ch == ',')
-                        {
-                            sb.Append(ch);
-                            sb.Append("\r\n");
-                            sb.Append('\t', indentation);
-                        }
-                        else if (ch == '[' || ch == '{')
-                        {
-                            sb.Append(ch);
-                            sb.Append("\r\n");
-                            sb.Append('\t', ++indentation);
-                        }
-                        else if (ch == ']' || ch == '}')
-                        {
-                            sb.Append("\r\n");
-                            sb.Append('\t', --indentation);
-                            sb.Append(ch);
-                        }
-                        else if (ch == ':')
-                        {
-                            sb.Append(ch);
-                            sb.Append('\t');
-                        }
-                        else
-                        {
-                            sb.Append(ch);
-                        }
-                    }
-                    else
-                    {
-                        sb.Append(ch);
-                    }
-                }
-            }
+        #region 读取
+        Boolean Read(String value);
 
-            return sb.ToString();
-        }
+        /// <summary>读取字节</summary>
+        /// <returns></returns>
+        Byte ReadByte();
         #endregion
     }
 
-    class JsonNet : IJson
+    /// <summary>IJson读写处理器接口</summary>
+    public interface IJsonHandler : IHandler<IJson>
     {
-        private static Type _Convert;
-        private static Type _Formatting;
-        private static Object _Set;
-        static JsonNet()
-        {
-            var type = "Newtonsoft.Json.JsonConvert".GetTypeEx();
-            if (type != null)
-            {
-                _Convert = type;
-                _Formatting = "Newtonsoft.Json.Formatting".GetTypeEx();
-                type = "Newtonsoft.Json.JsonSerializerSettings".GetTypeEx();
-
-                // 忽略循环引用
-                _Set = type.CreateInstance();
-                if (_Set != null) _Set.SetValue("ReferenceLoopHandling", 1);
-
-                // 自定义IContractResolver,用XmlIgnore特性作为忽略属性的方法
-                var sc = ScriptEngine.Create(_code, false);
-                sc.Compile();
-                if (sc.Method != null)
-                {
-                    _Set.SetValue("ContractResolver", sc.Method.DeclaringType.CreateInstance());
-                }
-
-                if (XTrace.Debug) XTrace.WriteLine("使用Json.Net,位于 {0}", _Convert.Assembly.Location);
-            }
-        }
-
-        private const String _code = @"
-class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
-{
-    protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
-    {
-        if (member.GetCustomAttribute<System.Xml.Serialization.XmlIgnoreAttribute>() != null) return null;
-
-        return base.CreateProperty(member, memberSerialization);
+        /// <summary>获取对象的Json字符串表示形式。</summary>
+        /// <param name="value"></param>
+        /// <returns>返回null表示不支持</returns>
+        String GetString(Object value);
     }
-    public static void Main() { }
-}";
 
-        /// <summary>是否支持</summary>
-        /// <returns></returns>
-        public static Boolean Support() { return _Convert != null; }
-
-        #region IJson 成员
-        public String Write(Object value, Boolean indented)
+    /// <summary>IJson读写处理器基类</summary>
+    public abstract class JsonHandlerBase : HandlerBase<IJson, IJsonHandler>, IJsonHandler
+    {
+        /// <summary>获取对象的Json字符串表示形式。</summary>
+        /// <param name="value"></param>
+        /// <returns>返回null表示不支持</returns>
+        public abstract String GetString(Object value);
+
+        /// <summary>写入一个对象</summary>
+        /// <param name="value">目标对象</param>
+        /// <param name="type">类型</param>
+        /// <returns>是否处理成功</returns>
+        public override Boolean Write(Object value, Type type)
         {
-            // 忽略循环引用
-            //var set = _Set.CreateInstance();
-            //if (set != null) set.SetValue("ReferenceLoopHandling", 1);
+            var v = GetString(value);
+            if (v == null) return false;
 
-            if (!indented)
-                return (String)_Convert.Invoke("SerializeObject", value, _Set);
-            else
-                return (String)_Convert.Invoke("SerializeObject", value, Enum.ToObject(_Formatting, 1), _Set);
-        }
+            Host.Write(v);
 
-        public Object Read(String json, Type type)
-        {
-            return _Convert.Invoke("DeserializeObject", json, type);
+            return true;
         }
-        #endregion
     }
 }
\ No newline at end of file
增加 +309 -0
diff --git a/NewLife.Core/Serialization/Json/IJsonHost.cs b/NewLife.Core/Serialization/Json/IJsonHost.cs
new file mode 100644
index 0000000..0d77868
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/IJsonHost.cs
@@ -0,0 +1,309 @@
+using System;
+using System.Reflection;
+using System.Text;
+using System.Web.Script.Serialization;
+using System.Xml.Serialization;
+using NewLife.Log;
+using NewLife.Reflection;
+
+namespace NewLife.Serialization
+{
+    /// <summary>Json序列化接口</summary>
+    public interface IJsonHost
+    {
+        /// <summary>写入对象,得到Json字符串</summary>
+        /// <param name="value"></param>
+        /// <param name="indented">是否缩进</param>
+        /// <returns></returns>
+        String Write(Object value, Boolean indented = false);
+
+        /// <summary>从Json字符串中读取对象</summary>
+        /// <param name="json"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        Object Read(String json, Type type);
+    }
+
+    /// <summary>Json助手</summary>
+    public static class JsonHelper
+    {
+        /// <summary>默认实现</summary>
+        public static IJsonHost Default { get; set; }
+
+        static JsonHelper()
+        {
+            if (JsonNet.Support())
+                Default = new JsonNet();
+            else
+                Default = new JsonDefault();
+        }
+
+        /// <summary>写入对象,得到Json字符串</summary>
+        /// <param name="value"></param>
+        /// <param name="indented">是否缩进</param>
+        /// <returns></returns>
+        public static String ToJson(this Object value, Boolean indented = false)
+        {
+            return Default.Write(value, indented);
+        }
+
+        /// <summary>从Json字符串中读取对象</summary>
+        /// <param name="json"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public static Object ToJsonEntity(this String json, Type type)
+        {
+            return Default.Read(json, type);
+        }
+
+        /// <summary>从Json字符串中读取对象</summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        public static T ToJsonEntity<T>(this String json)
+        {
+            return (T)Default.Read(json, typeof(T));
+        }
+    }
+
+    class JsonDefault : IJsonHost
+    {
+        //static JsonDefault()
+        //{
+        //    // 用XmlIgnore特性作为忽略属性的方法
+        //    var src = typeof(JavaScriptSerializer).GetMethodEx("CheckScriptIgnoreAttribute");
+        //    var dst = typeof(JsonDefault).GetMethodEx("CheckScriptIgnoreAttribute");
+        //    if (src != null && dst != null)
+        //    {
+        //        //new JavaScriptSerializer().Invoke(src, src);
+        //        //new JsonDefault().CheckScriptIgnoreAttribute(dst);
+        //        ApiHook.ReplaceMethod(src, dst);
+        //    }
+        //}
+
+        private bool CheckScriptIgnoreAttribute(MemberInfo memberInfo)
+        {
+            if (memberInfo.IsDefined(typeof(ScriptIgnoreAttribute), true)) return true;
+            if (memberInfo.IsDefined(typeof(XmlIgnoreAttribute), true)) return true;
+
+            return false;
+        }
+
+        #region IJsonHost 成员
+        public String Write(Object value, Boolean indented)
+        {
+            var json = new JavaScriptSerializer().Serialize(value);
+            //if (indented) json = Process(json);
+            if (indented) json = FormatOutput(json);
+
+            return json;
+        }
+
+        public Object Read(String json, Type type)
+        {
+            // 如果有必要,可以实现JavaScriptTypeResolver,然后借助Type.GetTypeEx得到更强的反射类型能力
+            return new JavaScriptSerializer().Deserialize(json, type);
+        }
+
+        //static String Process(String inputText)
+        //{
+        //    bool escaped = false;
+        //    bool inquotes = false;
+        //    int column = 0;
+        //    int indentation = 0;
+        //    var indentations = new Stack<int>();
+        //    int TABBING = 8;
+        //    var sb = new StringBuilder();
+        //    foreach (char x in inputText)
+        //    {
+        //        sb.Append(x);
+        //        column++;
+        //        if (escaped)
+        //        {
+        //            escaped = false;
+        //        }
+        //        else
+        //        {
+        //            if (x == '\\')
+        //            {
+        //                escaped = true;
+        //            }
+        //            else if (x == '\"')
+        //            {
+        //                inquotes = !inquotes;
+        //            }
+        //            else if (!inquotes)
+        //            {
+        //                if (x == ',')
+        //                {
+        //                    // if we see a comma, go to next line, and indent to the same depth
+        //                    sb.Append("\r\n");
+        //                    column = 0;
+        //                    for (int i = 0; i < indentation; i++)
+        //                    {
+        //                        sb.Append(" ");
+        //                        column++;
+        //                    }
+        //                }
+        //                else if (x == '[' || x == '{')
+        //                {
+        //                    // if we open a bracket or brace, indent further (push on stack)
+        //                    indentations.Push(indentation);
+        //                    indentation = column;
+        //                }
+        //                else if (x == ']' || x == '}')
+        //                {
+        //                    // if we close a bracket or brace, undo one level of indent (pop)
+        //                    indentation = indentations.Pop();
+        //                }
+        //                else if (x == ':')
+        //                {
+        //                    // if we see a colon, add spaces until we get to the next
+        //                    // tab stop, but without using tab characters!
+        //                    while ((column % TABBING) != 0)
+        //                    {
+        //                        sb.Append(' ');
+        //                        column++;
+        //                    }
+        //                }
+        //            }
+        //        }
+        //    }
+        //    return sb.ToString();
+        //}
+
+        static String FormatOutput(String json)
+        {
+            var sb = new StringBuilder();
+
+            bool escaping = false;
+            bool inQuotes = false;
+            int indentation = 0;
+
+            foreach (char ch in json)
+            {
+                if (escaping)
+                {
+                    escaping = false;
+                    sb.Append(ch);
+                }
+                else
+                {
+                    if (ch == '\\')
+                    {
+                        escaping = true;
+                        sb.Append(ch);
+                    }
+                    else if (ch == '\"')
+                    {
+                        inQuotes = !inQuotes;
+                        sb.Append(ch);
+                    }
+                    else if (!inQuotes)
+                    {
+                        if (ch == ',')
+                        {
+                            sb.Append(ch);
+                            sb.Append("\r\n");
+                            sb.Append('\t', indentation);
+                        }
+                        else if (ch == '[' || ch == '{')
+                        {
+                            sb.Append(ch);
+                            sb.Append("\r\n");
+                            sb.Append('\t', ++indentation);
+                        }
+                        else if (ch == ']' || ch == '}')
+                        {
+                            sb.Append("\r\n");
+                            sb.Append('\t', --indentation);
+                            sb.Append(ch);
+                        }
+                        else if (ch == ':')
+                        {
+                            sb.Append(ch);
+                            sb.Append('\t');
+                        }
+                        else
+                        {
+                            sb.Append(ch);
+                        }
+                    }
+                    else
+                    {
+                        sb.Append(ch);
+                    }
+                }
+            }
+
+            return sb.ToString();
+        }
+        #endregion
+    }
+
+    class JsonNet : IJsonHost
+    {
+        private static Type _Convert;
+        private static Type _Formatting;
+        private static Object _Set;
+        static JsonNet()
+        {
+            var type = "Newtonsoft.Json.JsonConvert".GetTypeEx();
+            if (type != null)
+            {
+                _Convert = type;
+                _Formatting = "Newtonsoft.Json.Formatting".GetTypeEx();
+                type = "Newtonsoft.Json.JsonSerializerSettings".GetTypeEx();
+
+                // 忽略循环引用
+                _Set = type.CreateInstance();
+                if (_Set != null) _Set.SetValue("ReferenceLoopHandling", 1);
+
+                // 自定义IContractResolver,用XmlIgnore特性作为忽略属性的方法
+                var sc = ScriptEngine.Create(_code, false);
+                sc.Compile();
+                if (sc.Method != null)
+                {
+                    _Set.SetValue("ContractResolver", sc.Method.DeclaringType.CreateInstance());
+                }
+
+                if (XTrace.Debug) XTrace.WriteLine("使用Json.Net,位于 {0}", _Convert.Assembly.Location);
+            }
+        }
+
+        private const String _code = @"
+class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
+{
+    protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
+    {
+        if (member.GetCustomAttribute<System.Xml.Serialization.XmlIgnoreAttribute>() != null) return null;
+
+        return base.CreateProperty(member, memberSerialization);
+    }
+    public static void Main() { }
+}";
+
+        /// <summary>是否支持</summary>
+        /// <returns></returns>
+        public static Boolean Support() { return _Convert != null; }
+
+        #region IJsonHost 成员
+        public String Write(Object value, Boolean indented)
+        {
+            // 忽略循环引用
+            //var set = _Set.CreateInstance();
+            //if (set != null) set.SetValue("ReferenceLoopHandling", 1);
+
+            if (!indented)
+                return (String)_Convert.Invoke("SerializeObject", value, _Set);
+            else
+                return (String)_Convert.Invoke("SerializeObject", value, Enum.ToObject(_Formatting, 1), _Set);
+        }
+
+        public Object Read(String json, Type type)
+        {
+            return _Convert.Invoke("DeserializeObject", json, type);
+        }
+        #endregion
+    }
+}
\ No newline at end of file
增加 +197 -0
diff --git a/NewLife.Core/Serialization/Json/Json.cs b/NewLife.Core/Serialization/Json/Json.cs
new file mode 100644
index 0000000..ccc5727
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/Json.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using NewLife.Log;
+using NewLife.Reflection;
+
+namespace NewLife.Serialization
+{
+    /// <summary>Json序列化</summary>
+    public class Json : FormatterBase, IJson
+    {
+        #region 属性
+        /// <summary>是否缩进</summary>
+        public Boolean Indented { get; set; }
+
+        /// <summary>处理器列表</summary>
+        public IList<IJsonHandler> Handlers { get; private set; }
+
+        //private StringBuilder _builder;
+        #endregion
+
+        #region 构造
+        /// <summary>实例化</summary>
+        public Json()
+        {
+            UseProperty = true;
+
+            //_builder = new StringBuilder();
+
+            // 遍历所有处理器实现
+            var list = new List<IJsonHandler>();
+            list.Add(new JsonGeneral { Host = this });
+            list.Add(new JsonComposite { Host = this });
+            list.Add(new JsonArray { Host = this });
+            //list.Add(new JsonDictionary { Host = this });
+            // 根据优先级排序
+            list.Sort();
+
+            Handlers = list;
+        }
+        #endregion
+
+        #region 处理器
+        /// <summary>添加处理器</summary>
+        /// <param name="handler"></param>
+        /// <returns></returns>
+        public Json AddHandler(IJsonHandler handler)
+        {
+            if (handler != null)
+            {
+                handler.Host = this;
+                Handlers.Add(handler);
+                // 根据优先级排序
+                (Handlers as List<IJsonHandler>).Sort();
+            }
+
+            return this;
+        }
+
+        /// <summary>添加处理器</summary>
+        /// <typeparam name="THandler"></typeparam>
+        /// <param name="priority"></param>
+        /// <returns></returns>
+        public Json AddHandler<THandler>(Int32 priority = 0) where THandler : IJsonHandler, new()
+        {
+            var handler = new THandler();
+            handler.Host = this;
+            if (priority != 0) handler.Priority = priority;
+
+            return AddHandler(handler);
+        }
+
+        /// <summary>获取处理器</summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public T GetHandler<T>() where T : class, IJsonHandler
+        {
+            foreach (var item in Handlers)
+            {
+                if (item is T) return item as T;
+            }
+
+            return default(T);
+        }
+        #endregion
+
+        #region 写入
+        /// <summary>写入一个对象</summary>
+        /// <param name="value">目标对象</param>
+        /// <param name="type">类型</param>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public virtual Boolean Write(Object value, Type type = null)
+        {
+            if (type == null)
+            {
+                if (value == null) return true;
+
+                type = value.GetType();
+
+                // 一般类型为空是顶级调用
+                if (Hosts.Count == 0) WriteLog("JsonWrite {0} {1}", type.Name, value);
+            }
+
+            //foreach (var item in Handlers)
+            //{
+            //    if (item.Write(value, type)) return true;
+            //}
+
+            var sb = new StringBuilder();
+            Write(sb, value);
+
+            Stream.Write(sb.ToString().GetBytes());
+
+            return false;
+        }
+
+        /// <summary>写入字符串</summary>
+        /// <param name="value"></param>
+        public virtual void Write(String value)
+        {
+            //_builder.Append(value);
+        }
+
+        public virtual void Write(StringBuilder sb, Object value)
+        {
+            if (value == null) return;
+            var type = value.GetType();
+
+            foreach (var item in Handlers)
+            {
+                if (item.Write(value, type)) return;
+            }
+        }
+        #endregion
+
+        #region 读取
+        /// <summary>读取指定类型对象</summary>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public virtual Object Read(Type type)
+        {
+            var value = type.CreateInstance();
+            if (!TryRead(type, ref value)) throw new Exception("读取失败!");
+
+            return value;
+        }
+
+        /// <summary>读取指定类型对象</summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public T Read<T>()
+        {
+            return (T)(Object)Read(typeof(T));
+        }
+
+        /// <summary>尝试读取指定类型对象</summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public virtual Boolean TryRead(Type type, ref Object value)
+        {
+            if (Hosts.Count == 0) WriteLog("JsonRead {0} {1}", type.Name, value);
+
+            foreach (var item in Handlers)
+            {
+                if (item.TryRead(type, ref value)) return true;
+            }
+            return false;
+        }
+
+        public virtual Boolean Read(String value)
+        {
+            return true;
+        }
+
+        /// <summary>读取字节</summary>
+        /// <returns></returns>
+        public virtual Byte ReadByte()
+        {
+            var b = Stream.ReadByte();
+            if (b < 0) throw new Exception("数据流超出范围!");
+            return (Byte)b;
+        }
+        #endregion
+
+        #region 辅助函数
+
+        #endregion
+    }
+}
\ No newline at end of file
增加 +124 -0
diff --git a/NewLife.Core/Serialization/Json/JsonArray.cs b/NewLife.Core/Serialization/Json/JsonArray.cs
new file mode 100644
index 0000000..25b6c4b
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/JsonArray.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using NewLife.Reflection;
+using System.Linq;
+
+namespace NewLife.Serialization
+{
+    /// <summary>列表数据编码</summary>
+    public class JsonArray : JsonHandlerBase
+    {
+        /// <summary>初始化</summary>
+        public JsonArray()
+        {
+            // 优先级
+            Priority = 20;
+        }
+
+        /// <summary>获取对象的Json字符串表示形式。</summary>
+        /// <param name="value"></param>
+        /// <returns>返回null表示不支持</returns>
+        public override String GetString(Object value)
+        {
+            if (value == null) return String.Empty;
+
+            var type = value.GetType();
+            if (type == typeof(Guid)) return ((Guid)value).ToString();
+            if (type == typeof(Byte[])) return Convert.ToBase64String((Byte[])value);
+            if (type == typeof(Char[])) return new String((Char[])value);
+
+            switch (Type.GetTypeCode(value.GetType()))
+            {
+                case TypeCode.Boolean:
+                    return value + "";
+                case TypeCode.Byte:
+                case TypeCode.SByte:
+                case TypeCode.Char:
+                    return value + "";
+                case TypeCode.DBNull:
+                case TypeCode.Empty:
+                    return String.Empty;
+                case TypeCode.DateTime:
+                    return value + "";
+                case TypeCode.Decimal:
+                    return value + "";
+                case TypeCode.Single:
+                case TypeCode.Double:
+                    return value + "";
+                case TypeCode.Int16:
+                case TypeCode.Int32:
+                case TypeCode.Int64:
+                case TypeCode.UInt16:
+                case TypeCode.UInt32:
+                case TypeCode.UInt64:
+                    return value + "";
+                case TypeCode.String:
+                    if (((String)value).IsNullOrEmpty()) return String.Empty;
+                    return "\"{0}\"".F(value);
+                case TypeCode.Object:
+                default:
+                    return null;
+            }
+        }
+
+        /// <summary>写入</summary>
+        /// <param name="value"></param>
+        /// <param name="type"></param>
+        /// <returns></returns>
+        public override bool Write(object value, Type type)
+        {
+            if (!typeof(IList).IsAssignableFrom(type)) return false;
+
+            var list = value as IList;
+
+            Host.Write("[");
+            if (list != null && list.Count > 0)
+            {
+                // 循环写入数据
+                foreach (var item in list)
+                {
+                    Host.Write(item);
+                }
+            }
+            Host.Write("]");
+
+            return true;
+        }
+
+        /// <summary>读取</summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public override bool TryRead(Type type, ref object value)
+        {
+            if (!typeof(IList).IsAssignableFrom(type)) return false;
+
+            // 先读取
+            if (!Host.Read("[")) return false;
+
+            // 子元素类型
+            var elmType = type.GetElementTypeEx();
+
+            var list = typeof(IList<>).MakeGenericType(elmType).CreateInstance() as IList;
+            while (!Host.Read("]"))
+            {
+                Object obj = null;
+                if (!Host.TryRead(elmType, ref obj)) return false;
+
+                list.Add(obj);
+            }
+
+            // 数组的创建比较特别
+            if (typeof(Array).IsAssignableFrom(type))
+            {
+                value = Array.CreateInstance(type.GetElementTypeEx(), list.Count);
+                list.CopyTo((Array)value, 0);
+            }
+            else
+                value = list;
+
+            return true;
+        }
+    }
+}
\ No newline at end of file
增加 +281 -0
diff --git a/NewLife.Core/Serialization/Json/JsonComposite.cs b/NewLife.Core/Serialization/Json/JsonComposite.cs
new file mode 100644
index 0000000..d528958
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/JsonComposite.cs
@@ -0,0 +1,281 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Xml.Serialization;
+using NewLife.Collections;
+using NewLife.Reflection;
+
+namespace NewLife.Serialization
+{
+    /// <summary>复合对象处理器</summary>
+    public class JsonComposite : JsonHandlerBase
+    {
+        /// <summary>要忽略的成员</summary>
+        public ICollection<String> IgnoreMembers { get; set; }
+
+        /// <summary>实例化</summary>
+        public JsonComposite()
+        {
+            Priority = 100;
+
+            //IgnoreMembers = new HashSet<String>(StringComparer.OrdinalIgnoreCase);
+            IgnoreMembers = new HashSet<String>();
+        }
+
+        /// <summary>获取对象的Json字符串表示形式。</summary>
+        /// <param name="value"></param>
+        /// <returns>返回null表示不支持</returns>
+        public override String GetString(Object value)
+        {
+            if (value == null) return String.Empty;
+
+            var type = value.GetType();
+            if (type == typeof(Guid)) return ((Guid)value).ToString();
+            if (type == typeof(Byte[])) return Convert.ToBase64String((Byte[])value);
+            if (type == typeof(Char[])) return new String((Char[])value);
+
+            switch (Type.GetTypeCode(value.GetType()))
+            {
+                case TypeCode.Boolean:
+                    return value + "";
+                case TypeCode.Byte:
+                case TypeCode.SByte:
+                case TypeCode.Char:
+                    return value + "";
+                case TypeCode.DBNull:
+                case TypeCode.Empty:
+                    return String.Empty;
+                case TypeCode.DateTime:
+                    return value + "";
+                case TypeCode.Decimal:
+                    return value + "";
+                case TypeCode.Single:
+                case TypeCode.Double:
+                    return value + "";
+                case TypeCode.Int16:
+                case TypeCode.Int32:
+                case TypeCode.Int64:
+                case TypeCode.UInt16:
+                case TypeCode.UInt32:
+                case TypeCode.UInt64:
+                    return value + "";
+                case TypeCode.String:
+                    if (((String)value).IsNullOrEmpty()) return String.Empty;
+                    return "\"{0}\"".F(value);
+                case TypeCode.Object:
+                default:
+                    return null;
+            }
+        }
+
+        /// <summary>写入对象</summary>
+        /// <param name="value">目标对象</param>
+        /// <param name="type">类型</param>
+        /// <returns></returns>
+        public override Boolean Write(Object value, Type type)
+        {
+            if (value == null) return false;
+
+            // 不支持基本类型
+            if (Type.GetTypeCode(type) != TypeCode.Object) return false;
+
+            var ms = GetMembers(type);
+            WriteLog("JsonWrite类{0} 共有成员{1}个", type.Name, ms.Count);
+
+            Host.Hosts.Push(value);
+
+            // 获取成员
+            foreach (var member in ms)
+            {
+                if (IgnoreMembers != null && IgnoreMembers.Contains(member.Name)) continue;
+
+                var mtype = GetMemberType(member);
+                Host.Member = member;
+
+                var v = value.GetValue(member);
+                WriteLog("    {0}.{1} {2}", type.Name, member.Name, v);
+
+                if (!Host.Write(v, mtype))
+                {
+                    Host.Hosts.Pop();
+                    return false;
+                }
+            }
+            Host.Hosts.Pop();
+
+            return true;
+        }
+
+        /// <summary>尝试读取指定类型对象</summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public override Boolean TryRead(Type type, ref Object value)
+        {
+            if (type == null)
+            {
+                if (value == null) return false;
+                type = value.GetType();
+            }
+
+            // 不支持基本类型
+            if (Type.GetTypeCode(type) != TypeCode.Object) return false;
+            // 不支持基类不是Object的特殊类型
+            //if (type.BaseType != typeof(Object)) return false;
+            if (!typeof(Object).IsAssignableFrom(type)) return false;
+
+            var ms = GetMembers(type);
+            WriteLog("JsonRead类{0} 共有成员{1}个", type.Name, ms.Count);
+
+            if (value == null) value = type.CreateInstance();
+
+            Host.Hosts.Push(value);
+
+            // 成员序列化访问器
+            var ac = value as IMemberAccessor;
+
+            // 获取成员
+            for (int i = 0; i < ms.Count; i++)
+            {
+                var member = ms[i];
+                if (IgnoreMembers != null && IgnoreMembers.Contains(member.Name)) continue;
+
+                var mtype = GetMemberType(member);
+                Host.Member = member;
+                WriteLog("    {0}.{1}", member.DeclaringType.Name, member.Name);
+
+                // 成员访问器优先
+                if (ac != null)
+                {
+                    // 访问器直接写入成员
+                    if (ac.Read(Host, member))
+                    {
+                        // 访问器内部可能直接操作Hosts修改了父级对象,典型应用在于某些类需要根据某个字段值决定采用哪个派生类
+                        var obj = Host.Hosts.Peek();
+                        if (obj != value)
+                        {
+                            value = obj;
+                            ms = GetMembers(value.GetType());
+                            ac = value as IMemberAccessor;
+                        }
+
+                        continue;
+                    }
+                }
+
+                Object v = null;
+                if (!Host.TryRead(mtype, ref v))
+                {
+                    Host.Hosts.Pop();
+                    return false;
+                }
+
+                value.SetValue(member, v);
+            }
+            Host.Hosts.Pop();
+
+            return true;
+        }
+
+        #region 获取成员
+        /// <summary>获取成员</summary>
+        /// <param name="type"></param>
+        /// <param name="baseFirst"></param>
+        /// <returns></returns>
+        protected virtual List<MemberInfo> GetMembers(Type type, Boolean baseFirst = true)
+        {
+            if (Host.UseProperty)
+                return GetProperties(type, baseFirst).Cast<MemberInfo>().ToList();
+            else
+                return GetFields(type, baseFirst).Cast<MemberInfo>().ToList();
+        }
+
+        private static DictionaryCache<Type, List<FieldInfo>> _cache1 = new DictionaryCache<Type, List<FieldInfo>>();
+        private static DictionaryCache<Type, List<FieldInfo>> _cache2 = new DictionaryCache<Type, List<FieldInfo>>();
+        /// <summary>获取字段</summary>
+        /// <param name="type"></param>
+        /// <param name="baseFirst"></param>
+        /// <returns></returns>
+        protected static List<FieldInfo> GetFields(Type type, Boolean baseFirst = true)
+        {
+            if (baseFirst)
+                return _cache1.GetItem(type, key => GetFields2(key, true));
+            else
+                return _cache2.GetItem(type, key => GetFields2(key, false));
+        }
+
+        static List<FieldInfo> GetFields2(Type type, Boolean baseFirst = true)
+        {
+            var list = new List<FieldInfo>();
+
+            // Void*的基类就是null
+            if (type == typeof(Object) || type.BaseType == null) return list;
+
+            if (baseFirst) list.AddRange(GetFields(type.BaseType));
+
+            var fis = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+            foreach (var fi in fis)
+            {
+                if (fi.GetCustomAttribute<NonSerializedAttribute>() != null) continue;
+
+                list.Add(fi);
+            }
+
+            if (!baseFirst) list.AddRange(GetFields(type.BaseType));
+
+            return list;
+        }
+
+        private static DictionaryCache<Type, List<PropertyInfo>> _cache3 = new DictionaryCache<Type, List<PropertyInfo>>();
+        private static DictionaryCache<Type, List<PropertyInfo>> _cache4 = new DictionaryCache<Type, List<PropertyInfo>>();
+        /// <summary>获取属性</summary>
+        /// <param name="type"></param>
+        /// <param name="baseFirst"></param>
+        /// <returns></returns>
+        protected static List<PropertyInfo> GetProperties(Type type, Boolean baseFirst = true)
+        {
+            if (baseFirst)
+                return _cache3.GetItem(type, key => GetProperties2(key, true));
+            else
+                return _cache4.GetItem(type, key => GetProperties2(key, false));
+        }
+
+        static List<PropertyInfo> GetProperties2(Type type, Boolean baseFirst = true)
+        {
+            var list = new List<PropertyInfo>();
+
+            // Void*的基类就是null
+            if (type == typeof(Object) || type.BaseType == null) return list;
+
+            if (baseFirst) list.AddRange(GetProperties(type.BaseType));
+
+            var pis = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+            foreach (var pi in pis)
+            {
+                if (pi.GetIndexParameters().Length > 0) continue;
+                if (pi.GetCustomAttribute<XmlIgnoreAttribute>() != null) continue;
+
+                list.Add(pi);
+            }
+
+            if (!baseFirst) list.AddRange(GetProperties(type.BaseType));
+
+            return list;
+        }
+
+        static Type GetMemberType(MemberInfo member)
+        {
+            switch (member.MemberType)
+            {
+                case MemberTypes.Field:
+                    return (member as FieldInfo).FieldType;
+                case MemberTypes.Property:
+                    return (member as PropertyInfo).PropertyType;
+                default:
+                    throw new NotSupportedException();
+            }
+        }
+        #endregion
+    }
+}
\ No newline at end of file
增加 +10 -0
diff --git a/NewLife.Core/Serialization/Json/JsonDictionary.cs b/NewLife.Core/Serialization/Json/JsonDictionary.cs
new file mode 100644
index 0000000..1e21ca4
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/JsonDictionary.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NewLife.Serialization
+{
+    class JsonDictionary
+    {
+    }
+}
增加 +96 -0
diff --git a/NewLife.Core/Serialization/Json/JsonGeneral.cs b/NewLife.Core/Serialization/Json/JsonGeneral.cs
new file mode 100644
index 0000000..29161bf
--- /dev/null
+++ b/NewLife.Core/Serialization/Json/JsonGeneral.cs
@@ -0,0 +1,96 @@
+using System;
+using NewLife.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace NewLife.Serialization
+{
+    /// <summary>Json基础类型处理器</summary>
+    public class JsonGeneral : JsonHandlerBase
+    {
+        /// <summary>实例化</summary>
+        public JsonGeneral()
+        {
+            Priority = 10;
+        }
+
+        /// <summary>获取对象的Json字符串表示形式。</summary>
+        /// <param name="value"></param>
+        /// <returns>返回null表示不支持</returns>
+        public override String GetString(Object value)
+        {
+            if (value == null) return String.Empty;
+
+            var type = value.GetType();
+            if (type == typeof(Guid)) return ((Guid)value).ToString();
+            if (type == typeof(Byte[])) return Convert.ToBase64String((Byte[])value);
+            if (type == typeof(Char[])) return new String((Char[])value);
+
+            switch (Type.GetTypeCode(value.GetType()))
+            {
+                case TypeCode.Boolean:
+                    return value + "";
+                case TypeCode.Byte:
+                case TypeCode.SByte:
+                case TypeCode.Char:
+                    return value + "";
+                case TypeCode.DBNull:
+                case TypeCode.Empty:
+                    return String.Empty;
+                case TypeCode.DateTime:
+                    return value + "";
+                case TypeCode.Decimal:
+                    return value + "";
+                case TypeCode.Single:
+                case TypeCode.Double:
+                    return value + "";
+                case TypeCode.Int16:
+                case TypeCode.Int32:
+                case TypeCode.Int64:
+                case TypeCode.UInt16:
+                case TypeCode.UInt32:
+                case TypeCode.UInt64:
+                    return value + "";
+                case TypeCode.String:
+                    if (((String)value).IsNullOrEmpty()) return String.Empty;
+                    return "\"{0}\"".F(value);
+                case TypeCode.Object:
+                default:
+                    return null;
+            }
+        }
+
+        /// <summary>尝试读取指定类型对象</summary>
+        /// <param name="type"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public override Boolean TryRead(Type type, ref Object value)
+        {
+            if (type == null)
+            {
+                if (value == null) return false;
+                type = value.GetType();
+            }
+
+            //if (type == typeof(Guid))
+            //{
+            //    value = new Guid(ReadBytes(16));
+            //    return true;
+            //}
+            //else if (type == typeof(Byte[]))
+            //{
+            //    value = ReadBytes(-1);
+            //    return true;
+            //}
+            //else if (type == typeof(Char[]))
+            //{
+            //    value = ReadChars(-1);
+            //    return true;
+            //}
+
+            return false;
+        }
+    }
+}
\ No newline at end of file
修改 +10 -9
diff --git a/Test/Program.cs b/Test/Program.cs
index 38ff7fc..7dfcaea 100644
--- a/Test/Program.cs
+++ b/Test/Program.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Reflection;
+using System.Text;
 using System.Threading;
 using System.Xml.Serialization;
 using NewLife.Common;
@@ -104,16 +105,16 @@ namespace Test
 
         static void Test4()
         {
-            //var buf = "41-54-0d-0d-0a-0d-0a-4F-4B-0d-0a".ToHex();
-            //Console.WriteLine(buf.ToHex());
-            //Console.WriteLine(buf.ToStr());
-            //MQTest.TestBase();
+            var user = UserX.FindAll()[0];
+            Console.WriteLine(user);
 
-            var ns = new Int32[] { 123, 0, -456, Int32.MinValue, Int32.MaxValue };
-            foreach (var item in ns)
-            {
-                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", item, (UInt32)item, (Int64)(UInt32)item, (Int64)item, (UInt64)item);
-            }
+            var sb = new StringBuilder();
+
+            var json = new Json();
+            json.Log = XTrace.Log;
+            json.Write(sb, user);
+
+            Console.WriteLine(sb.ToString());
         }
 
         static void Test5()