我记录网站综合系统 -- 技术原理解析[5:JSON 序列化 反序列化]

源代码位置:wojilu\Serialization

wojilu作为一个成熟的框架,不但有整个完整的MVC框架,还具有很多可以独立供大家使用的功能模块。

可能您已经有自己的框架了,不过,您还是可以使用尝试一下他所提供的小类库,帮助你提高开发效率。

这节就来介绍一下JSON的序列化和反序列化。

整个JSON的类库的方法入口时JSON.cs文件中的JSON类。我们看看他所具有的各种方法吧:

这里主要是各种发序列化的功能

/// 将字典序列化为 json 字符串
public static String DicToString( Dictionary<String, object> dic ) 
/// 将 json 字符串反序列化为对象
public static Object ToObject( String oneJsonString, Type t )
/// 将 json 字符串反序列化为对象
public static T ToObject<T>( String jsonString )
/// 将 json 字符串反序列化为对象列表
public static List<T> ToList<T>( String jsonString )
/// 将 json 字符串反序列化为字典对象的列表
public static List<Dictionary<String, object>> ToDictionaryList( String jsonString ) 
/// 将 json 字符串反序列化为字典对象
public static Dictionary<String, object> ToDictionary( String oneJsonString )

在另一个类JsonString.cs中,我们可以看到很多序列化的功能

 

 1         /// <param name="isBreakline">是否换行(默认不换行,阅读起来更加清晰)</param>
 2         /// <param name="withQuotation">属性名是否使用引号(默认不启用)</param>
 3 
 4 /// 将对象转换成 json 字符串
 5 public static String Convert( Object obj )
 6 public static String Convert( Object obj, Boolean isBreakline ) 
 7 /// 将对象数组转换成 json 字符串
 8 public static String ConvertArray( object[] arrObj )
 9 /// 将对象列表转换成 json 字符串
10 public static String ConvertList( IList list ) 
11 public static String ConvertList( IList list, Boolean isBreakline ) 
12 /// 将字典 Dictionary 转换成 json 字符串
13 public static String ConvertDictionary( IDictionary dic )
14 public static String ConvertDictionary( IDictionary dic, Boolean isBreakline )
15 /// 将对象转换成 json 字符串
16 public static String ConvertObject( Object obj )
17 public static String ConvertObject( Object obj, Boolean isBreakline )
18 public static String ConvertObject( Object obj, Boolean isBreakline, Boolean withQuotation )

 

拥有这么多函数,可以将很多复杂对象转换为JSON,也可以还原JSON为复杂对象了。

当然这是一篇技术文章,我们还是要从技术角度来分析一下wojilu的JSON的技术面的东西。

说到复杂对象的序列化,以前的XML,Android的Parcel对象[前段时间在研究Android(本人研究范围从Winform到ASP到Mainfraim到DB),里面也有一个序列化的Parcel对象,Java写的],现在的JSON,思想都是一样的。

1。通过反射Reflection来获得类里面的所有属性,如果属性是基本对象[那些值引用,放在栈上的家伙们],直接调用相应序列化方法,序列化成JSON,遇上非基本类型,继续递归,遍历非基本对象的所有属性,能序列化的序列化,不行继续递归。

反射的语句:

PropertyInfo[] properties = obj.GetType().GetProperties( BindingFlags.Public | BindingFlags.Instance );

遍历所有属性,能序列化就序列化

 

            foreach (PropertyInfo info in propertyList) {
                
if (info.IsDefined( typeof( NotSerializeAttribute ), false )) {
                    
continue;
                }
                Object propertyValue 
= ReflectionUtil.GetPropertyValue( obj, info.Name );

                String jsonValue;
                
if (info.PropertyType.IsArray) {
                    jsonValue 
= ConvertArray( (object[])propertyValue );
                }
                
else if (rft.IsInterface( info.PropertyType, typeof( IList ) )) {
                    jsonValue 
= ConvertList ( (IList)propertyValue, isBreakline );
                }
                
else {
                    jsonValue 
= Convert( propertyValue, isBreakline );
                }

                
if (withQuotation) {
                    builder.AppendFormat( 
"\"{0}\":{1}", info.Name, jsonValue );
                }
                
else {
                    builder.AppendFormat( 
"{0}:{1}", info.Name, jsonValue );
                }

                builder.Append( 
"" );
                
if (isBreakline) builder.AppendLine();

            }
            String result 
= builder.ToString().Trim().TrimEnd( ',' );
            
if (isBreakline) result += Environment.NewLine;
            
return result + " }";
        }

2.各种基本类型的序列化

  

   字符串的序列化:转义符的处理。

   转义符,就是那些引号,斜杠 等家伙们。他们混在字符串里面,但是并非是字符串。

   在将对象转化为字符串的时候,如果遇上字符串转为JSON字符串的时候,请注意这些小地方的处理。  

            if (t == typeof( String )) {
                
return "\"" + obj.ToString().Replace( @"\"@"\\" ).Replace( "\"""\\" + "\"" ).Replace( "\r""" ).Replace( "\n""" ) + "\""// 转义双引号,消除换行
            }

 日期的序列化 在日期前后加上 斜杠

if (t == typeof( DateTime )) return "\"" + obj.ToString() + "\"";

逻辑值的序列化:转换为小写

if (t == typeof( Boolean )) return obj.ToString().ToLower();

数字:直接转换

 

おまけ:

一时忍不住,贡献一下我以前VBNET的XML序列化的代码,作为礼物给大家。。。。我写了10年VB了。。。

 

  1 Imports System
  2 Imports System.Xml
  3 Imports System.Xml.Serialization
  4 Imports System.IO
  5 Imports Microsoft.VisualBasic
  6 ''' <summary>
  7 ''' 将对象或哈希表从文件读取或写入的方法集合
  8 ''' </summary>
  9 ''' <remarks></remarks>
 10 Public Module IOSystemBase
 11     ''' <summary>
 12     ''' 从二进制文件中读取哈希表
 13     ''' </summary>
 14     ''' <param name="StrFileName">文件名</param>
 15     ''' <returns>哈希表</returns>
 16     ''' <remarks></remarks>
 17     Function ReadHashTableFromBinaryFile(ByVal StrFileName As StringAs Hashtable
 18         Dim ReturnHashTable As Hashtable
 19 
 20         Dim formatter = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
 21         Dim stream = New IO.FileStream(StrFileName, IO.FileMode.Open)
 22         Try
 23             ReturnHashTable = CType(formatter.Deserialize(stream), Hashtable)
 24         Catch
 25             ReturnHashTable = Nothing
 26         Finally
 27             stream.Close()
 28         End Try
 29         Return ReturnHashTable
 30     End Function
 31     ''' <summary>
 32     ''' 将哈希表写入二进制文件
 33     ''' </summary>
 34     ''' <param name="strFileName">文件名</param>
 35     ''' <param name="obj">哈希表</param>
 36     ''' <remarks></remarks>
 37     Sub WriteHashTableToBinaryFile(ByVal strFileName As StringByVal obj As Hashtable)
 38         Dim formatter = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
 39         Dim stream = New IO.FileStream(strFileName, IO.FileMode.OpenOrCreate)
 40         formatter.Serialize(stream, obj)
 41         stream.Close()
 42     End Sub
 43     ''' <summary>
 44     ''' 从XML文件中读取哈希表
 45     ''' </summary>
 46     ''' <param name="StrFileName">文件名</param>
 47     ''' <returns>哈希表</returns>
 48     ''' <remarks></remarks>
 49     Function ReadHashTableXMLFile(ByVal StrFileName As StringAs Hashtable
 50         Dim ReturnHashTable As Hashtable
 51         Dim formatter = New System.Xml.Serialization.XmlSerializer(GetType(Hashtable))
 52         Dim stream = New IO.FileStream(StrFileName, IO.FileMode.Open)
 53         Try
 54             ReturnHashTable = CType(formatter.Deserialize(stream), Hashtable)
 55         Catch
 56             ReturnHashTable = Nothing
 57         Finally
 58             stream.Close()
 59         End Try
 60         Return ReturnHashTable
 61     End Function
 62     ''' <summary>
 63     ''' 将哈希表写入XML文件
 64     ''' </summary>
 65     ''' <param name="strFileName">文件名</param>
 66     ''' <param name="obj">哈希表</param>
 67     ''' <remarks></remarks>
 68     Sub WriteHashTableToXMLFile(ByVal strFileName As StringByVal obj As Hashtable)
 69         Dim formatter = New System.Xml.Serialization.XmlSerializer(GetType(Hashtable))
 70         Dim stream = New IO.FileStream(strFileName, IO.FileMode.OpenOrCreate)
 71         formatter.Serialize(stream, obj)
 72         stream.Close()
 73     End Sub
 74     ''' <summary>
 75     ''' 将可XML序列化对象写入XML文件
 76     ''' </summary>
 77     ''' <param name="obj">对象</param>
 78     ''' <param name="mType">类型</param>
 79     ''' <param name="FileName">文件名</param>
 80     ''' <remarks>如果对象是不可序列化的类型,将返回错误</remarks>
 81     Sub WriteObjectToXMLFile(ByVal obj As ObjectByVal mType As Type, ByVal FileName As String)
 82         ' Use the constructor that takes a type and XmlRootAttribute.
 83         Dim serializer As New XmlSerializer(mType)
 84         Dim writer As New StreamWriter(FileName)
 85         serializer.Serialize(writer, obj)
 86         writer.Close()
 87     End Sub
 88     ''' <summary>
 89     ''' 从XML文件读取对象
 90     ''' </summary>
 91     ''' <param name="mType">类型</param>
 92     ''' <param name="FileName">文件名</param>
 93     ''' <returns>对象</returns>
 94     ''' <remarks>如果对象是不可序列化的类型,将返回错误</remarks>
 95     Function ReadObjectFromXMLFile(ByVal mType As Type, ByVal FileName As StringAs Object
 96         Dim serializer As New XmlSerializer(mType)
 97         Dim Reader As New StreamReader(FileName)
 98         Dim Rtn As Object
 99         Rtn = serializer.Deserialize(Reader)
100         Reader.Close()
101         Return Rtn
102     End Function
103     ''' <summary>
104     ''' 如果没有指定目录,则创建
105     ''' </summary>
106     ''' <param name="strDirectoryPath">指定目录</param>
107     ''' <remarks></remarks>
108     Sub CreateDirectoryWhenNotExists(ByVal strDirectoryPath As String)
109         If IO.Directory.Exists(strDirectoryPath) = False Then
110             IO.Directory.CreateDirectory(strDirectoryPath)
111         End If
112     End Sub
113 End Module

 

 

我记录网址 http://www.wojilu.com/

欢迎大家加入我记录开发团队

 

 

posted @ 2011-06-14 14:35  灰毛毛  阅读(2352)  评论(6编辑  收藏  举报