我记录网站综合系统 -- 技术原理解析[5:JSON 序列化 反序列化]
源代码位置:wojilu\Serialization
wojilu作为一个成熟的框架,不但有整个完整的MVC框架,还具有很多可以独立供大家使用的功能模块。
可能您已经有自己的框架了,不过,您还是可以使用尝试一下他所提供的小类库,帮助你提高开发效率。
这节就来介绍一下JSON的序列化和反序列化。
整个JSON的类库的方法入口时JSON.cs文件中的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中,我们可以看到很多序列化的功能
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,遇上非基本类型,继续递归,遍历非基本对象的所有属性,能序列化的序列化,不行继续递归。
反射的语句:
遍历所有属性,能序列化就序列化
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字符串的时候,请注意这些小地方的处理。
return "\"" + obj.ToString().Replace( @"\", @"\\" ).Replace( "\"", "\\" + "\"" ).Replace( "\r", "" ).Replace( "\n", "" ) + "\""; // 转义双引号,消除换行
}
日期的序列化 在日期前后加上 斜杠
逻辑值的序列化:转换为小写
数字:直接转换
おまけ:
一时忍不住,贡献一下我以前VBNET的XML序列化的代码,作为礼物给大家。。。。我写了10年VB了。。。
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 String) As 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 String, ByVal 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 String) As 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 String, ByVal 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 Object, ByVal 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 String) As 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/
欢迎大家加入我记录开发团队