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 { /// /// TOP JSON响应通用解释器。 /// public class TopJsonParser : ITopParser where T : TopResponse { private static readonly ReaderWriterLock rwLock = new ReaderWriterLock(); private static readonly Dictionary> attrs = new Dictionary>(); #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 = null; // 忽略根节点的名称 foreach (object key in json.Keys) { data = json[key] as IDictionary; break; } if (data != null) { ITopReader reader = new TopJsonReader(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 GetTopAttributes(Type type) { Dictionary 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(); } 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 pas = GetTopAttributes(type); Dictionary.Enumerator em = pas.GetEnumerator(); while (em.MoveNext()) { KeyValuePair 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; } } }