`
carver
  • 浏览: 50287 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于Xml Attribute与Jayrock的纯.NET 2.0 JSON解释器实现

    博客分类:
  • .NET
阅读更多
经过同样的缓存优化后,JSON解释器在性能上要比微软自带的XML解释器慢10倍左右[XML为0.15ms,JSON为1.56ms],不过由于JSON的返回结果要比XML小一些,相对于网络IO的性能,这个1毫秒级别的性能差距也就可以忽略不计了
    /// <summary>
    /// TOP API响应解释器接口。响应格式可以是XML, JSON等等。
    /// </summary>
    /// <typeparam name="T">领域对象</typeparam>
    public interface ITopParser<T>
    {
        /// <summary>
        /// 把响应字符串解释成相应的领域对象。
        /// </summary>
        /// <param name="body">响应字符串</param>
        /// <returns>领域对象</returns>
        T Parse(string body);
    }
 
public delegate object DTopConvert(ITopReader reader, Type type);
 
    /// <summary>
    /// TOP API响应读取器接口。响应格式可以是XML, JSON等等。
    /// </summary>
    public interface ITopReader
    {
        /// <summary>
        /// 判断响应中是否包含指定的属性。
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <returns>true/false</returns>
        bool HasReturnField(object name);

        /// <summary>
        /// 获取值类型属性的值。
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <returns>值对象</returns>
        object GetPrimitiveObject(object name);

        /// <summary>
        /// 获取引用类型的值。
        /// </summary>
        /// <param name="name">属性名称</param>
        /// <param name="type">引用类型</param>
        /// <param name="convert">转换器</param>
        /// <returns>引用对象</returns>
        object GetReferenceObject(object name, Type type, DTopConvert convert);

        /// <summary>
        /// 获取列表类型的值。
        /// </summary>
        /// <param name="listName">列表属性名称</param>
        /// <param name="itemName">列表项名称</param>
        /// <param name="type">引用类型</param>
        /// <param name="convert">转换器</param>
        /// <returns>列表对象</returns>
        IList GetListObjects(string listName, string itemName, Type type, DTopConvert convert);
    }
 
    public class TopAttribute
    {
        public string ItemName { get; set; }
        public Type ItemType { get; set; }
        public string ListName { get; set; }
        public Type ListType { get; set; }
        public MethodInfo Method { get; set; }
    }
 
   /// <summary>
    /// TOP JSON响应通用读取器。
    /// </summary>
    public class TopJsonReader : ITopReader
    {
        private IDictionary json;

        public TopJsonReader(IDictionary json)
        {
            this.json = json;
        }

        public bool HasReturnField(object name)
        {
            return json.Contains(name);
        }

        public object GetPrimitiveObject(object name)
        {
            return json[name];
        }

        public object GetReferenceObject(object name, Type type, DTopConvert convert)
        {
            IDictionary dict = json[name] as IDictionary;
            if (dict != null && dict.Count > 0)
            {
                return convert(new TopJsonReader(dict), type);
            }
            else
            {
                return null;
            }
        }

        public IList GetListObjects(string listName, string itemName, Type type, DTopConvert convert)
        {
            IList listObjs = null;

            IDictionary jsonMap = json[listName] as IDictionary;
            if (jsonMap != null && jsonMap.Count > 0)
            {
                IList jsonList = jsonMap[itemName] as IList;
                if (jsonList != null && jsonList.Count > 0)
                {
                    Type listType = typeof(List<>).MakeGenericType(new Type[] { type });
                    listObjs = Activator.CreateInstance(listType) as IList;
                    foreach (object item in jsonList)
                    {
                        if (typeof(IDictionary).IsAssignableFrom(item.GetType())) // object
                        {
                            IDictionary subMap = item as IDictionary;
                            object subObj = convert(new TopJsonReader(subMap), type);
                            if (subObj != null)
                            {
                                listObjs.Add(subObj);
                            }
                        }
                        else if (typeof(IList).IsAssignableFrom(item.GetType())) // list/array
                        {
                            // TODO not support yet
                        }
                        else // boolean, long, double, string, null
                        {
                            listObjs.Add(item);
                        }
                    }
                }
            }

            return listObjs;
        }
    }
 
    /// <summary>
    /// TOP JSON响应通用解释器。
    /// </summary>
    public class TopJsonParser<T> : ITopParser<T> where T : TopResponse
    {
        private static Hashtable attrs = Hashtable.Synchronized(new Hashtable());

        public T Parse(string body)
        {
            T rsp = null;

            IDictionary json = JsonConvert.Import(body) as IDictionary;
            if (json != null)
            {
                IDictionary data = null;

                // 忽略根节点的名称
                foreach (object key in json.Keys)
                {
                    data = json[key] as IDictionary;
                    break;
                }

                if (data != null)
                {
                    ITopReader reader = new TopJsonReader(data);
                    rsp = (T)TopJsonConvert(reader, typeof(T));
                }
            }

            if (rsp == null)
            {
                rsp = Activator.CreateInstance<T>();
            }

            if (rsp != null)
            {
                rsp.Body = body;
            }

            return rsp;
        }

        private static Dictionary<string, TopAttribute> GetTopAttributes(Type type)
        {
            Dictionary<string, TopAttribute> tas = attrs[type.FullName] as Dictionary<string, TopAttribute>;
            if (tas != null) // 从缓存中获取类属性元数据
            {
                return tas;
            }
            else // 创建新的类属性元数据缓存
            {
                tas = new Dictionary<string, TopAttribute>();
            }

            PropertyInfo[] pis = type.GetProperties();
            foreach (PropertyInfo pi in pis)
            {
                TopAttribute ta = new TopAttribute();
                ta.Method = pi.GetSetMethod();

                // 获取对象属性名称
                XmlElementAttribute[] xeas = pi.GetCustomAttributes(typeof(XmlElementAttribute), true) as XmlElementAttribute[];
                if (xeas != null && xeas.Length > 0)
                {
                    ta.ItemName = xeas[0].ElementName;
                }

                // 获取列表属性名称
                if (ta.ItemName == null)
                {
                    XmlArrayItemAttribute[] xaias = pi.GetCustomAttributes(typeof(XmlArrayItemAttribute), true) as XmlArrayItemAttribute[];
                    if (xaias != null && xaias.Length > 0)
                    {
                        ta.ItemName = xaias[0].ElementName;
                    }
                    XmlArrayAttribute[] xaas = pi.GetCustomAttributes(typeof(XmlArrayAttribute), true) as XmlArrayAttribute[];
                    if (xaas != null && xaas.Length > 0)
                    {
                        ta.ListName = xaas[0].ElementName;
                    }
                    if (ta.ListName == null)
                    {
                        continue;
                    }
                }

                // 获取属性类型
                if (pi.PropertyType.IsGenericType)
                {
                    Type[] types = pi.PropertyType.GetGenericArguments();
                    ta.ListType = types[0];
                }
                else
                {
                    ta.ItemType = pi.PropertyType;
                }

                tas.Add(pi.Name, ta);
            }

            if (!attrs.ContainsKey(type.FullName))
            {
                attrs.Add(type.FullName, tas);
            }

            return tas;
        }

        protected static readonly DTopConvert TopJsonConvert = delegate(ITopReader reader, Type type)
        {
            object rsp = null;
            Dictionary<string, TopAttribute> pas = GetTopAttributes(type);

            Dictionary<string, TopAttribute>.Enumerator em = pas.GetEnumerator();
            while (em.MoveNext())
            {
                KeyValuePair<string, TopAttribute> kvp = em.Current;
                TopAttribute ta = kvp.Value;
                string itemName = ta.ItemName;
                string listName = ta.ListName;

                if (!reader.HasReturnField(itemName) && (string.IsNullOrEmpty(listName) || !reader.HasReturnField(listName)))
                {
                    continue;
                }

                object value = null;
                if (ta.ListType != null)
                {
                    value = reader.GetListObjects(listName, itemName, ta.ListType, TopJsonConvert);
                }
                else
                {
                    if (typeof(string) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            value = tmp.ToString();
                        }
                    }
                    else if (typeof(long) == ta.ItemType)
                    {
                        object tmp = reader.GetPrimitiveObject(itemName);
                        if (tmp != null)
                        {
                            if (typeof(string) == tmp.GetType())
                            {
                                long num = 0L;
                                long.TryParse(tmp.ToString(), out num);
                                value = num;
                            }
                            else
                            {
                                value = ((IConvertible)tmp).ToInt64(null);
                            }
                        }
                    }
                    else if (typeof(bool) == ta.ItemType)
                    {
                        value = reader.GetPrimitiveObject(itemName);
                    }
                    else
                    {
                        value = reader.GetReferenceObject(itemName, ta.ItemType, TopJsonConvert);
                    }
                }

                if (value != null)
                {
                    if (rsp == null)
                    {
                        rsp = Activator.CreateInstance(type);
                    }
                    ta.Method.Invoke(rsp, new object[] { value });
                }
            }

            return rsp;
        };
    }
分享到:
评论

相关推荐

    Migrate an ASP.NET 1.1 Web Page Using the CodeBehind Attribute to ASP.NET 2.0

    在 ASP.NET 2.0 中,引入了一种新的 Web 页面代码隐藏模型,它基于部分类(partial classes),这种模型可以更好地分离页面的标记与代码。 #### 迁移步骤详解 1. **理解 ASP.NET 2.0 中的新代码隐藏模型** - 在 ...

    asp.net 2.0 xml 电子书 pdf

    从给定的文件信息来看,该电子书主要探讨了ASP.NET 2.0与XML的高级编程技术,尤其聚焦于如何使用C#语言处理XML数据。以下是对标题、描述及部分展示内容中提及的关键知识点的深入解析: ### ASP.NET 2.0与XML ASP...

    asp.net2.0权限管理系统

    ASP.NET 2.0 权限管理系统是一款专为管理和控制用户访问权限而设计的应用程序,它在企业级软件开发中扮演着重要角色。系统的核心功能包括用户管理、角色分配以及权限控制,旨在确保数据安全性和操作合规性。下面将...

    ASP.NET 2.0中的partial

    在ASP.NET 2.0中,引入了“partial”这一概念,它主要用于C# 2.0中,通过局部类型(partial types)的方式使得开发人员能够将一个类、结构或接口分解到多个.cs文件中进行定义与实现。这种做法对于大型项目而言具有...

    ajaxpro2.dll for .net 2.0.rar

    AjaxPro2.dll是针对.NET Framework 2.0版本的一个组件,主要用于实现ASP.NET应用程序中的Ajax功能。Ajax(Asynchronous JavaScript and XML)技术允许在不刷新整个网页的情况下,通过后台与服务器进行异步数据交换,...

    网上商城系统(ASP.NET 2.0+SQL Server 2005)

    网上商城系统是一个基于ASP.NET 2.0和SQL Server 2005技术构建的电子商务平台,它提供了全面的功能,使商家能够在线销售商品和服务。ASP.NET 2.0是微软开发的一种强大的Web应用程序框架,它扩展了.NET Framework的...

    visual studio C#高级编程手册PDF,Simon Robinson,基于.net2.0讲解,是非常好的教程。

    12. **XML与Web服务**:探讨XML的解析、序列化,以及如何创建和消费ASMX和WCF Web服务。 13. **设计模式**:讲解一些常见的设计模式,如工厂模式、单例模式、观察者模式等,以及如何在C#中实现它们。 14. **...

    .net中attribute实现方法调用拦截(就是aop)

    在.NET中,我们可以通过Attribute来实现AOP的功能,这就是标题中提到的"attribute实现方法调用拦截"。 Attribute的使用通常是通过定义自定义Attribute类,然后在需要的地方应用这些特性。例如,我们可以创建一个`...

    ASP.NET MVC5 新特性:Attribute路由使用详解

    要启用Attribute路由,首先需要确保你的应用程序是基于ASP.NET MVC5构建的。接着,在应用程序启动时注册Attribute路由功能,具体来说是在`RouteConfig.cs`文件中添加以下代码: ```csharp public static void ...

    Microsoft .NET Framework 2.0-Application Development Foundation

    根据提供的信息,我们可以深入探讨与Microsoft .NET Framework 2.0-Application Development Foundation相关的知识点。 ### 1. 类型安全的自定义字典 在.NET Framework 2.0中,为了确保字典类型的安全性,可以使用...

    Attribute在.net编程中的应用

    Attribute在.NET编程中的应用是一个关键的概念,它允许程序员在代码中添加元数据,这些元数据可以为运行时环境提供额外的信息,或者影响程序的行为。在.NET框架中,Attribute不仅仅是一个关键字,而是一个类,它是...

    XML.zip_vb.net x

    这主要得益于.NET Framework中的System.Xml命名空间,其中包含许多类,如XmlNode、XmlElement、XmlDocument等,它们帮助程序员方便地与XML交互。 2. **创建XML文档** 在VB.NET中创建XML文档,我们通常会使用`Xml...

    中美 IT 培训 C# Asp.net 全套笔记1

    (160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...

    用.NET操作XML

    在.NET框架中,XML(eXtensible Markup Language)是一种常用的数据交换格式,因其结构化、自解释且易于解析的特点,被广泛应用于各种应用程序中,包括数据存储、配置文件、Web服务交互等。本篇文章将深入探讨如何...

    中美 IT 培训 C# Asp.net 笔记3

    (160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...

    中美 IT 培训 C# Asp.net 笔记2

    (160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...

    Android中xml转json

    另外,还有专门处理XML与JSON转换的库,如`org.json.XML`(这个库并非Android SDK自带,需要单独导入)。 - 添加第三方库的依赖到项目中,如在Gradle中添加: ```groovy implementation '...

    Asp.net Core 3.1基于AspectCore实现AOP实现事务、缓存拦截器功能

    最近想给我的框架加一种功能,就是比如给一个方法加一个事务的特性Attribute,那这个方法就会启用事务处理。给一个方法加一个缓存特性,那这个方法就会进行缓存。 这个也是网上说的面向切面编程AOP。 AOP的概念也很...

    Pro C# 7: With .NET and .NET Core

    along with four brand new chapters on Microsoft’s lightweight, cross-platform framework, .NET Core, up to and including .NET Core 2.0. Coverage of ASP.NET Core, Entity Framework (EF) Core, and more,...

    Attribute在.net编程中的应用(全).doc

    ### Attribute在.NET编程中的应用详解 #### 一、Attribute概述 在.NET编程中,Attribute是一个极为重要的特性,它类似于Java中的注解。Attribute主要用于为.NET框架中的类型、字段、方法和属性等添加元数据信息。...

Global site tag (gtag.js) - Google Analytics