| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using FastJSON;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Threading;
- using System.Xml.Serialization;
- namespace Top.Api.Parser
- {
- /// <summary>
- /// TOP JSON响应通用解释器。
- /// </summary>
- public class DingTalkJsonParser<T> : ITopParser<T> where T : TopResponse
- {
- private static readonly ReaderWriterLock rwLock = new ReaderWriterLock();
- private static readonly Dictionary<string, Dictionary<string, TopAttribute>> attrs = new Dictionary<string, Dictionary<string, TopAttribute>>();
- #region ITopParser Members
- public virtual T Parse(string body)
- {
- return Parse(body, typeof(T));
- }
- public T Parse(string body, Type type)
- {
- T rsp = null;
- IDictionary json = JSON.Parse(body) as IDictionary;
- if (json != null)
- {
- IDictionary data = json;
- if (data != null)
- {
- ITopReader reader = new TopSimplifyJsonReader(data);
- rsp = (T)FromJson(reader, type);
- }
- }
- if (rsp == null)
- {
- rsp = Activator.CreateInstance(type) as T;
- }
- if (rsp != null)
- {
- rsp.Body = body;
- }
- return rsp;
- }
- #endregion
- private Dictionary<string, TopAttribute> GetTopAttributes(Type type)
- {
- Dictionary<string, TopAttribute> tas = null;
- bool inc = false;
- rwLock.AcquireReaderLock(50);
- try
- {
- if (rwLock.IsReaderLockHeld)
- {
- inc = attrs.TryGetValue(type.FullName, out tas);
- }
- }
- finally
- {
- if (rwLock.IsReaderLockHeld)
- {
- rwLock.ReleaseReaderLock();
- }
- }
- if (inc && 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);
- }
- rwLock.AcquireWriterLock(50);
- try
- {
- if (rwLock.IsWriterLockHeld)
- {
- attrs[type.FullName] = tas;
- }
- }
- finally
- {
- if (rwLock.IsWriterLockHeld)
- {
- rwLock.ReleaseWriterLock();
- }
- }
- return tas;
- }
- public object FromJson(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, FromJson);
- }
- else
- {
- if (typeof(string) == ta.ItemType)
- {
- object tmp = reader.GetPrimitiveObject(itemName);
- if (typeof(string) == tmp.GetType())
- {
- value = tmp;
- }
- else
- {
- if (tmp != null)
- {
- value = JSON.ToJSON(tmp);
- }
- }
- }
- else if (typeof(long) == ta.ItemType)
- {
- object tmp = reader.GetPrimitiveObject(itemName);
- if (typeof(long) == tmp.GetType())
- {
- value = tmp;
- }
- else
- {
- if (tmp != null)
- {
- value = long.Parse(tmp.ToString());
- }
- }
- }
- else if (typeof(bool) == ta.ItemType)
- {
- object tmp = reader.GetPrimitiveObject(itemName);
- if (typeof(bool) == tmp.GetType())
- {
- value = tmp;
- }
- else
- {
- if (tmp != null)
- {
- value = bool.Parse(tmp.ToString());
- }
- }
- }
- else
- {
- value = reader.GetReferenceObject(itemName, ta.ItemType, FromJson);
- }
- }
- if (value != null)
- {
- if (rsp == null)
- {
- rsp = Activator.CreateInstance(type);
- }
- ta.Method.Invoke(rsp, new object[] { value });
- }
- }
- return rsp;
- }
- }
- }
|