好久没有做web了,JSON目前比较流行,闲得没事,所以动手试试将对象序列化为JSON字符(尽管DotNet Framework已经有现成的库,也有比较好的第三方开源库),而且只是实现了处理简单的类型,并且DateTime处理的也不专业,有兴趣的筒子可以扩展,代码比较简单,反序列化木有实现:( ,直接贴代码吧,都有注释了,所以废话不多说 :)
测试类
/// <summary> /// Nested class of Person. /// </summary> public class House { public string Name { get ; set ; } public double Price { get ; set ; } } /// <summary> /// Person dummy class /// </summary> public class Person { public string Name { get ; set ; } public int Age { get ; set ; } public string Address { get ; set ; } private int h = 12 ; public bool IsMarried { get ; set ; } public string [] Names { get ; set ; } public int [] Ages { get ; set ; } public House MyHouse { get ; set ; } public DateTime BirthDay { get ; set ; } public List < string > Friends { get ; set ; } public List < int > LoveNumbers { get ; set ; } }
接口定义
/// <summary> /// IJsonSerializer interface. /// </summary> interface IJsonSerializer { /// <summary> /// Serialize object to json string. /// </summary> /// <typeparam name="T"> The type to be serialized. </typeparam> /// <param name="obj"> Instance of the type T. </param> /// <returns> json string. </returns> string Serialize( object obj); /// <summary> /// Deserialize json string to object. /// </summary> /// <typeparam name="T"> The type to be deserialized. </typeparam> /// <param name="jsonString"> json string. </param> /// <returns> instance of type T. </returns> T Deserialize < T > ( string jsonString); }
接口实现,还有待完善..
/// <summary> /// Implement IJsonSerializer, but Deserialize had not been implemented. /// </summary> public class JsonSerializer : IJsonSerializer { /// <summary> /// Serialize object to json string. /// </summary> /// <typeparam name="T"> The type to be serialized. </typeparam> /// <param name="obj"> Instance of the type T. </param> /// <returns> json string. </returns> public string Serialize( object obj) { if (obj == null ) { return " {} " ; } // Get the type of obj. Type t = obj.GetType(); // Just deal with the public instance properties. others ignored. BindingFlags bf = BindingFlags.Instance | BindingFlags.Public; PropertyInfo[] pis = t.GetProperties(bf); StringBuilder json = new StringBuilder( " { " ); if (pis != null && pis.Length > 0 ) { int i = 0 ; int lastIndex = pis.Length - 1 ; foreach (PropertyInfo p in pis) { // Simple string if (p.PropertyType.Equals( typeof ( string ))) { json.AppendFormat( " \"{0}\":\"{1}\" " , p.Name, p.GetValue(obj, null )); } // Number,boolean. else if (p.PropertyType.Equals( typeof ( int )) || p.PropertyType.Equals( typeof ( bool )) || p.PropertyType.Equals( typeof ( double )) || p.PropertyType.Equals( typeof ( decimal )) ) { json.AppendFormat( " \"{0}\":{1} " , p.Name, p.GetValue(obj, null ).ToString().ToLower()); } // Array. else if (isArrayType(p.PropertyType)) { // Array case. object o = p.GetValue(obj, null ); if (o == null ) { json.AppendFormat( " \"{0}\":{1} " , p.Name, " null " ); } else { json.AppendFormat( " \"{0}\":{1} " , p.Name, getArrayValue((Array)p.GetValue(obj, null ))); } } // Class type. custom class, list collections and so forth. else if (isCustomClassType(p.PropertyType)) { object v = p.GetValue(obj, null ); if (v is IList) { IList il = v as IList; string subJsString = getIListValue(il); json.AppendFormat( " \"{0}\":{1} " , p.Name, subJsString); } else { // Normal class type. string subJsString = Serialize(p.GetValue(obj, null )); json.AppendFormat( " \"{0}\":{1} " , p.Name, subJsString); } } // Datetime else if (p.PropertyType.Equals( typeof (DateTime))) { DateTime dt = (DateTime)p.GetValue(obj, null ); if (dt == default (DateTime)) { json.AppendFormat( " \"{0}\":\"\" " , p.Name); } else { json.AppendFormat( " \"{0}\":\"{1}\" " , p.Name, ((DateTime)p.GetValue(obj, null )).ToString( " yyyy-MM-dd HH:mm:ss " )); } } else { // TODO: extend. } if (i >= 0 && i != lastIndex) { json.Append( " , " ); } ++ i; } } json.Append( " } " ); return json.ToString(); } /// <summary> /// Deserialize json string to object. /// </summary> /// <typeparam name="T"> The type to be deserialized. </typeparam> /// <param name="jsonString"> json string. </param> /// <returns> instance of type T. </returns> public T Deserialize < T > ( string jsonString) { throw new NotImplementedException( " Not implemented :( " ); } /// <summary> /// Get array json format string value. /// </summary> /// <param name="obj"> array object </param> /// <returns> js format array string. </returns> string getArrayValue(Array obj) { if (obj != null ) { if (obj.Length == 0 ) { return " [] " ; } object firstElement = obj.GetValue( 0 ); Type et = firstElement.GetType(); bool quotable = et == typeof ( string ); StringBuilder sb = new StringBuilder( " [ " ); int index = 0 ; int lastIndex = obj.Length - 1 ; if (quotable) { foreach (var item in obj) { sb.AppendFormat( " \"{0}\" " , item.ToString()); if (index >= 0 && index != lastIndex) { sb.Append( " , " ); } ++ index; } } else { foreach (var item in obj) { sb.Append(item.ToString()); if (index >= 0 && index != lastIndex) { sb.Append( " , " ); } ++ index; } } sb.Append( " ] " ); return sb.ToString(); } return " null " ; } /// <summary> /// Get Ilist json format string value. /// </summary> /// <param name="obj"> IList object </param> /// <returns> js format IList string. </returns> string getIListValue(IList obj) { if (obj != null ) { if (obj.Count == 0 ) { return " [] " ; } object firstElement = obj[ 0 ]; Type et = firstElement.GetType(); bool quotable = et == typeof ( string ); StringBuilder sb = new StringBuilder( " [ " ); int index = 0 ; int lastIndex = obj.Count - 1 ; if (quotable) { foreach (var item in obj) { sb.AppendFormat( " \"{0}\" " , item.ToString()); if (index >= 0 && index != lastIndex) { sb.Append( " , " ); } ++ index; } } else { foreach (var item in obj) { sb.Append(item.ToString()); if (index >= 0 && index != lastIndex) { sb.Append( " , " ); } ++ index; } } sb.Append( " ] " ); return sb.ToString(); } return " null " ; } /// <summary> /// Check whether t is array type. /// </summary> /// <param name="t"></param> /// <returns></returns> bool isArrayType(Type t) { if (t != null ) { return t.IsArray; } return false ; } /// <summary> /// Check whether t is custom class type. /// </summary> /// <param name="t"></param> /// <returns></returns> bool isCustomClassType(Type t) { if (t != null ) { return t.IsClass && t != typeof ( string ); } return false ; } }
测试代码:
class Program { static void Main( string [] args) { Person ps = new Person() { Name = " Leon " , Age = 25 , Address = " China " , IsMarried = false , Names = new string [] { " wgc " , " leon " , " giantfish " }, Ages = new int [] { 1 , 2 , 3 , 4 }, MyHouse = new House() { Name = " HouseName " , Price = 100.01 , }, BirthDay = new DateTime( 1986 , 12 , 20 , 12 , 12 , 10 ), Friends = new List < string > () { " friend1 " , " friend2 " }, LoveNumbers = new List < int > () { 1 , 2 , 3 } }; IJsonSerializer js = new JsonSerializer(); string s = js.Serialize(ps); Console.WriteLine(s); Console.ReadKey(); } }
生成的 JSON字符串 :
{ " Name " : " Leon " , " Age " : 25 , " Address " : " China " , " IsMarried " : false , " Names " :[ " wgc " , " leon " , " giantfish " ], " Ages " :[ 1 , 2 , 3 , 4 ], " MyHouse " :{ " Name " : " HouseName " , " Price " : 100.01 }, " BirthDay " : " 1986-12-20 12:12:10 " , " Friends " :[ " friend1 " , " friend2 " ], " LoveNumbers " :[ 1 , 2 , 3 ]}
嗯 ,就这样子,没有研究开源的JSON代码是如何实现的,应该也是拼接字符串吧,上面的代码再多测试,完善下,应该也差不多可以投产了 :)