ASP.NET用SQL Server中的數據來生成JSON字符串
最近在學習ExtJs與ASP.NET結合開發,前者用到的數據內容基本上都是JSON格式,遂想寫一個格式化數據成JSON的東東,在網上找了一下,發現還蠻多的,實現了一個類似于ToString()的方法,名曰:ToJson()。
不過在網上看到的基本上都是屬于SCOTT大作的臨摹版,90%以上都一樣(我并不是說SCOTT大蝦的杰作有什么不好,沒有那個意思),于是我也照著葫蘆畫了一個瓢。廢話就不多說了,直接進入正題。
先說說我的開發環境:
Windows Server 2008 DataCenter
Visual Studio 2008 Team System
SQL Server 2005 Developer(SQL 2008已經正式發布了,準備升級,^_^)
我照著SCOTT的大作(本文末有原著以及中文版鏈接)寫了一個ToJson()出來。代碼如下:
using System; using System.Web.Script.Serialization; namespace Demo { /// <summary> /// JSON幫助類 /// </summary> public static class JsonHelper { /// <summary> /// 格式化成Json字符串 /// </summary> /// <param name="obj">需要格式化的對象</param> /// <returns>Json字符串</returns> public static string ToJson(this object obj) { JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(obj); } /// <summary> /// 格式化成Json字符串 /// </summary> /// <param name="obj">需要格式化的對象</param> /// <param name="recursionDepth">指定序列化的深度</param> /// <returns>Json字符串</returns> public static string ToJson(this object obj, int recursionDepth) { JavaScriptSerializer serializer = new JavaScriptSerializer(); serializer.RecursionLimit = recursionDepth; return serializer.Serialize(obj); } } }
一字不漏的照打,應該沒有問題吧(后來發現SCOTT大作末尾的Note,忘記看了,真是粗心啊~~~*_*)!
但是在編輯的時候,雖然是成功了,但是發現有2個警告,由于本人寫程序一直都是盡自己最大努力來保證所寫程序的警告數量最少,所以,當然要看看這兩個警告到底是什么東東。
警告是:“System.Web.Script.Serialization.JavaScriptSerializer.JavaScriptSerializer()”已過時:“The recommended alternative is System.Runtime.Serialization.DataContractJsonSerializer.”
記得剛開始學習ASP.NET的時候,在用AppSettings的時候(具體哪個方法記不清了)也出現過類似的警告,最后是用ConfigurationManager代替就沒有出現過該警告了,那這次應該也差不多吧。
于是到MSDN看看是怎么回事。沒弄明白,再到CSDN看看呢。還是沒弄明白,最后,求助一下Google。NND,折騰了半天,還是不知道到底是什么回事。
用“DataContractJsonSerializer”來代替吧,但是又少了對“System.Runtime.Serialization”的引用,把引用添加上吧,還是沒有編譯通過。
一直不知道是怎么回事,最后,幸運的Google到一個Demo,也是用“DataContractJsonSerializer”來代替上訴過時警告的。SCOTT大作中末尾Note給出的鏈接。
總算是明白怎么回事了。解決步驟如下:
首先,添加兩個DLL的引用,分別是:System.Runtime.Serialization.dll、System.ServiceModel.Web.dll。
添加完引用之后,在cs代碼頁中添加using語句,如下:
using System; using System.IO; using System.Runtime.Serialization.Json;
注:因為要用到Stream等東東,所以這里要添加上System.IO這個命名空間。
總共三條using語句,在添加完之后,就可以開始寫代碼了,代碼如下:
namespace Demo { /// <summary> /// JSON幫助類 /// </summary> public static class JsonHelper { /// <summary> /// 格式化成Json字符串 /// </summary> /// <param name="obj">需要格式化的對象</param> /// <returns>Json字符串</returns> public static string ToJson(this object obj) { // 首先,當然是JSON序列化 DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); // 定義一個stream用來存發序列化之后的內容 Stream stream = new MemoryStream(); serializer.WriteObject(stream, obj); // 從頭到尾將stream讀取成一個字符串形式的數據,并且返回 stream.Position = 0; StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } } }
到此,該類的編寫就完成了,剩下的就是調用了。
首先在Visual Studio 2008中新建一個庫類項目(名稱任意),將上述的內容添加到該項目中去,編譯成一個dll文件供WebApplication(或WebSite)調用。我這里建的工程叫做Demo,編譯出來的dll叫做Demo.dll。
然后在SQL Server 2005中新建一個數據庫,在Web.config中配置好鏈接字符串,反正可以讀取數據就行,這里就不再詳述了。我這里建的數據庫叫做Test,表名為Test_Table_01,字段有:TestID(int),Title(varchar(50)),Body(varchar(200)),Remark(varchar(200)),字段內添加了一些內容。
在Visual Studio 2008中新建一個WebApplication(也可以是WebSite),然后添加上述Demo.dll的引用,別慌,還需要添加“System.Runtime.Serialization”的引用,因為在后面添加實體層的時候,需要對實體層的屬性進行序列化。我這里新建的是WebApplication,名稱叫做Test。
然后在Test中添加了App_Code文件夾,在里面添加了一個類,叫做TestClass.cs。
該類就用于映射數據庫Test中的表Test_Table_01,添加好cs文件之后,寫入如下代碼(C# 3.5的新特性^_^):
using System; using System.Runtime.Serialization; namespace Test { [DataContract] public class TestClass { [DataMember] public int TestID { get; set; } [DataMember] public string Title { get; set; } [DataMember] public string Body { get; set; } [DataMember] public string Remark { get; set; } } }
注:如果要對該類進行序列化,一定要在類前面添加上“[DataContract]”,在屬性前面添加上“[DataMember]”,這樣才能被“DataContractJsonSerializer”序列化成JSON。
在添加好TestClass.cs文件之后,在根目錄新建一個Default.aspx頁面,在頁面中放一個Label,轉到后臺代碼。
在cs代碼上面添加“using Demo;”、“using System.Collections.Generic;”和“using System.Data.SqlClient;”這三條using語句。
然后新建一個方法,用于獲取數據庫中的數據,并且將獲取出來的內容填入泛型中(這里給出的代碼中,DataAccess是我自己根據SqlHelper重寫的一個數據庫訪問類,其實直接用SqlHelper就可以了),代碼如下:
// 獲取表中的所有數據 private List<TestClass> GetAllData() { List<TestClass> list = new List<TestClass>(); string strSql = "SELECT * FROM Test_Table_01"; SqlCommand cmd = new SqlCommand(strSql); DataAccess da = new DataAccess(); try { SqlDataReader sdr = da.ExecuteReader(cmd); while (sdr.Read()) { list.Add(this.FillDetailWithReader(sdr)); } } finally { da.DisConnect(); } return list; } // 向泛型填充數據 private TestClass FillDetailWithReader(SqlDataReader reader) { TestClass model = new TestClass(); if (reader["TestID"] != DBNull.Value) model.TestID = (int)reader["TestID"]; if (reader["Title"] != DBNull.Value) model.Title = (string)reader["Title"]; if (reader["Body"] != DBNull.Value) model.Body = (string)reader["Body"]; if (reader["Remark"] != DBNull.Value) model.Remark = (string)reader["Remark"]; return model; }
這兩個方法寫好之后,就可以調用了。在Page_Load事件里面輸入以下代碼:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 首先調用GetAllData()方法獲取數據庫中的數據 List<TestClass> list = this.GetAllData(); // 將泛型list格式化成JSON字符串,并且賦值到Label1中去 Label1.Text = list.ToJson(); } }
到此,就完成了從SQL Server中讀取數據、格式化成JSON字符串、并且輸入的過程。
如今網上有很多這方面的內容,比如什么用LINQ讀取啊,或者不用SQL Server,用XML等等,就靠大家自己去摸索的。
下一步目標:不知道大家注意到沒有,上面SCOTT大作里面對ToJson()進行了重載,而我寫的ToJson()方法只有一個,少了一個重載,這個就是我的下一步目標,希望是在沒有警告的情況下,將序列化深度的自定義研究出來。