经过同样的缓存优化后,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;
};
}
分享到:
相关推荐
How to- Migrate an ASP.NET 1.1 Web Page Using the CodeBehind Attribute to ASP.NET 2.0
包含2篇attribute高级应用文章,以及相应的代码。 代码关键处,都有详细注释。 看过后,你会对attribute,context有更深刻的认识
(160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...
(160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...
(160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;详细地讲授Web Service及其应用和相关的安全性问题、WSE(Web Services Enhancements)、SOAP、WSDL、UDDI、Windows Service、VSS...
最近想给我的框架加一种功能,就是比如给一个方法加一个事务的特性Attribute,那这个方法就会启用事务处理。给一个方法加一个缓存特性,那这个方法就会进行缓存。 这个也是网上说的面向切面编程AOP。 AOP的概念也很...
读了《Attribute在.net编程中的应用》,对Attribute的认识会加深,对编程很有帮助哦!
此文档详细的介绍了.NET下 自定义Attribute的应用,对于理解.NET AOP下的技术实现非常有帮助
Version 2.4.0 has been released: xml-rpc.net.2.4.0.zip New feature and fixed issues: New StructParams property on XmlRpcMethodAttribute which provides supports for APIs which use a struct to ...
Attribute在.net编程中的应用(全).doc ,.net的高级特性,类似JAVA中的标注。
此文档详细讲解了:ASP.NET MVC5 新特性:Attribute路由的使用,非常的详细,值得学习。
详细介绍了Attribute属性在.NET中的应用 适合初级人员,
第二阶段教学内容安排(400课时) 课程名称 课程内容 培训目的 ASP.Net2.0、ADO.Net2.0和Web 应用程序 (160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;...
第二阶段教学内容安排(400课时) 课程名称 课程内容 培训目的 ASP.Net2.0、ADO.Net2.0和Web 应用程序 (160课时) 系统讲授 ASP.Net2.0、ADO.Net2.0、 基于数据库的WEB应用程序、的开发;...
6.4 ADO.NET与XML 266 6.4.1 读XML文档到DataSet 266 6.4.2 DataSet转为XML文档 267 6.5 项目案例1:实现网站的RSS应用 267 6.6 项目案例2:在线实现RSS阅读器 270 本章常见技术面试题 275 常见面试技巧之经典问题...
该示例代码是针对asp.net core mvc权限管理的一种实现方式,不一定是最好的,但是能满足权限的有效控制
6.4 ADO.NET与XML 266 6.4.1 读XML文档到DataSet 266 6.4.2 DataSet转为XML文档 267 6.5 项目案例1:实现网站的RSS应用 267 6.6 项目案例2:在线实现RSS阅读器 270 本章常见技术面试题 275 常见面试技巧之经典问题...
ASP.NET MVC5增删改查,包含LINQ和ADO两种(ADO只实现了List Detail和Delete,Edit留给你自己思考了),LINQ版本实现了完整的CRUD,并且演示了MVC5 的新特性Attribute Route以及异步的修改、删除控制器。
Corsolas AOP Attributed Framework for .NET 2.0 是一种处理面向切面编程的创新方式,基于属性,无需外部语言,以简单而强大的方式做到最好...... by maxtuno。