一、簡介與執行個體
Jayrock是一個LGPL的開源的軟體,實作了JSON和JSON-RPC,支援微軟ASP.NET架構。
JSON+Jayrock+ASP.NET Quick Start :http://jayrock.berlios.de/#quick-start
JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 簡介
特點:
簡單格式化的資料交換
2、易于人們的讀寫習慣
3、易于機器的分析和運作
4、JavaScript中使用eval()方法可以很友善的讀取 JSON資料
5、JSON支援的語言ActionScript, C, C#, ColdFusion, E, Java, JavaScript, ML, Objective CAML, Perl, PHP, Python, Rebol, Ruby, and Lua.
下載下傳位址:http://developer.berlios.de/project/showfiles.php?group_id=4638
執行個體如下:
實體類User.cs:
public class User
{
public User()
//
// TODO: 在此處添加構造函數邏輯
}
private int id;
public int Id
get { return id; }
set { id = value; }
private string name;
public string Name
get { return name; }
set { name = value; }
private DateTime time;
public DateTime Time
get { return time; }
set { time = value; }
private double money;
public double Money
get { return money; }
set { money = value; }
private string[] str;
public string[] Str
get { return str; }
set { str = value; }
頁面背景功能:
把實體轉成JSON:
User user = new User();
user.Id = 1;
user.Name = "你";
user.Money = 2.3;
user.Time = DateTime.Now;
user.Str = new string[] { "1", "2", "3" };
Jayrock.Json.JsonTextWriter writer = new Jayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(user, writer);
string str = writer.ToString();
//str等于{"id":1,"name":"你","time":"2009-04-14T14:29:29.4375000+08:00","money":2.3,"str":["1","2","3"]}
JSON轉成實體:
string str = "{\"id\":1,\"name\":\"你\",\"time\":\"2009-04-13T22:21:11.6562500+08:00\",\"money\":2.3,\"str\":[\"1\",\"2\",\"3\"]}";
User user = (User)Jayrock.Json.Conversion.JsonConvert.Import(typeof(User), str);
把數組轉成JSON:
writer.WriteStartArray();
writer.WriteString("1");
writer.WriteString("a");
writer.WriteString("3");
writer.WriteEndArray();
string str = writer.ToString();//str : ["1","a","3"]
writer.WriteStartObject();
writer.WriteMember("WID");//屬性名
writer.WriteNumber(11);
writer.WriteMember("Date");//屬性名
writer.WriteString(DateTime.Now.ToString());
writer.WriteEndObject();
JSON擷取屬性:
string str = "{\"WID\":11,\"Date\":\"2009-4-14 14:02:42\"}";
Jayrock.Json.JsonTextReader reader = new Jayrock.Json.JsonTextReader(new StringReader(str));
while (reader.Read())
if (reader.TokenClass == JsonTokenClass.String || reader.TokenClass == JsonTokenClass.Number)
this.Label9.Text = this.Label9.Text + "," + reader.Text;
//顯示:11,2009-4-14 14:02:42
注:
{"id":1,"name":"你","time":"2009-04-14T14:29:29.4375000+08:00","money":2.3,"str":["1","2","3"]}這種JSON中的時間字元串是這樣的:"2009-04-14T14:29:29.4375000+08:00",在前台要這樣解析這個字元串:
<script type="text/javascript" src="JS/json2.js"></script> //引用json的JS檔案
//"2009-04-13T22:21:11.6562500+08:00" 解析這種類型
function getOtherTime(data)
var str = data.split(".")[0].replace(/T/g, " ");
var da = parseDate(str);
return da.getFullYear()+"年"+ (da.getMonth()+1)+"月" +da.getDate()+"日" +da.getHours()+":"+da.getMinutes()+":"+da.getSeconds();
/*
将String類型解析為Date類型.
parseDate('2006-1-1') return new Date(2006,0,1)
parseDate(' 2006-1-1 ') return new Date(2006,0,1)
parseDate('2006-1-1 15:14:16') return new Date(2006,0,1,15,14,16)
parseDate(' 2006-1-1 15:14:16 ') return new Date(2006,0,1,15,14,16);
parseDate('2006-1-1 15:14:16.254') return new Date(2006,0,1,15,14,16,254)
parseDate(' 2006-1-1 15:14:16.254 ') return new Date(2006,0,1,15,14,16,254)
parseDate('不正确的格式') retrun null
*/
function parseDate(str){
if(typeof str == 'string'){
var results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) *$/);
if(results && results.length>3)
return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]));
results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2}) *$/);
if(results && results.length>6)
return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),parseInt(results[4]),parseInt(results[5]),parseInt(results[6]));
results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})\.(\d{1,9}) *$/);
if(results && results.length>7)
return new Date(parseInt(results[1]),parseInt(results[2]) -1,parseInt(results[3]),parseInt(results[4]),parseInt(results[5]),parseInt(results[6]),parseInt(results[7]));
}
return null;
将Date/String類型,解析為String類型.
傳入String類型,則先解析為Date類型
不正确的Date,傳回 ''
如果時間部分為0,則忽略,隻傳回日期部分.
function formatDate(v){
if(typeof v == 'string') v = parseDate(v);
if(v instanceof Date){
var y = v.getFullYear();
var m = v.getMonth() + 1;
var d = v.getDate();
var h = v.getHours();
var i = v.getMinutes();
var s = v.getSeconds();
var ms = v.getMilliseconds();
if(ms>0) return y + '-' + m + '-' + d + ' ' + h + ':' + i + ':' + s + '.' + ms;
if(h>0 || i>0 || s>0) return y + '-' + m + '-' + d + ' ' + h + ':' + i + ':' + s;
return y + '-' + m + '-' + d;
return '';
二、json與類的互相轉換
1. Json Object轉Model —— js定義json對象傳遞到背景業務類,背景接收後,轉為資料模型。
Json Object = { 'KId':1, 'IndexDirectory':‘c:\root’}
轉換方法:
KdgPointData kpd = (KdgPointData)JsonConvert.Import(typeof(KdgPointData), jsonObject.ToString());
KdgPointData就是資料模型類,使用JsonConvert對象需要引用兩個動态連結庫(位址見文章附錄),并添加: using Jayrock.Json.Conversion;
Import()方法重載了5次,這裡用到的是,第一個參數為你想轉換的類型,第二個參數為json object轉為string後的結果。
注意:在背景接收js對象,都用object來接收,也就是說,上面的jsonObject在c#方法類中,是一個object對象,轉換後,才是model。而且jsonObject中元素的個數,key的大小寫都要跟Model中的屬性保持一直。
2. Model轉Json Object —— 這個不需要轉變,直接将Model或者Model[]作為方法的傳回類型,在js那邊接收後,定義對應的JsonReader,就可以了。
如果你在定義Ext.data.store使用了proxy屬性,并定義了相應的url,那麼Jayrock倒有一個将Model轉為符合json格式字元串的方法:
string temp = JsonConvert.ExportToString(model);
然後,Response.Write(temp); Response.End(); 如此請求這個url後,進而獲得Json資料。
3. DataTable轉Json Object —— 這個有兩種做法,一種是将DataTable轉為Model或Model[],再通過第二種方式轉換,或者自己寫一個方法拼接json 字元串:
/// <summary> DataTable二維表格轉為符合json格式的字元串 </summary>
/// <param name="tableSource">資料庫查詢結果</param>
/// <param name="fields">需要添加進來的字段名</param>
/// <returns></returns>
public string DataTableToJson(DataTable tableSource, string[] fields)
{
string jsonData = "{'totalCount':" + tableSource.Rows.Count + ",'root':[";
if (tableSource.Rows.Count > 0)
{
foreach (DataRow row in tableSource.Rows)
{
jsonData += "{";
for (int i = 0; i < fields.Length; i++)
jsonData += "'" + fields[i] + "':'" + row[fields[i]] + "',";
jsonDatajsonData = jsonData.Substring(0, jsonData.Length - 1);
jsonData += "},";
}
jsonDatajsonData = jsonData.Substring(0, jsonData.Length - 1);
jsonData += "]}";
}
else
return jsonData;
}
封裝後格式為{
totalCount : 6,
root : [
{'id' : 1, 'name' : 'lislie' }, { 'id' : 2, 'name' : 'Mark' }...
]
使用方法:string temp = DataTableToJson(dt, {"id", "name"});
三、json2.js的使用介紹
JavaScript使用了ECMAScript語言規範第三版進行了标準化。
JSON是JavaScript面向對象文法的一個子集。由于JSON是JavaScript的一個子集,是以它運用于此語言中。
var myJSONObject = {"bindings": [
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"},
{"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"
{"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"
};
上面的示例,建立了一個包括單獨成員”bindings”的對象,此成員包括一個含有三個對象
(”ircEvent”, “method”, 與 “regex”)的數組
成員可以通過 成員可以通過.或者下标操作符檢索 或者下标操作符檢索。
myJSONObject.bindings[0].method // "newURI"
1. 使用eval()函數:
為了将JSON文本轉換為對象,可以使用文本轉換為對象,可以使用eval()函數調用JavaScript編輯器。由于JSON是JavaScript的子集,是以編譯器将正确的解析文本并産生對象結構。文本必須括在括号中避免産生JavaScript的文法歧義。
var myObject = eval('(' + myJSONtext + ')');
eval函數非常快速。
它可以編譯執行任何JavaScript程式,是以産生了安全性問題。
當使用可信任與完善的源代碼時才可以使用eval函 數。
這樣可以更安全的使用JSON解析器。
使用XMLHttpRequest的web應用,頁面之間的通訊隻允許同源,是以是可以信任的。但這卻不是完善的。
如果伺服器沒有嚴謹的JSON編碼,或者沒有嚴格的輸入驗證,那麼可能傳送包括危險腳本的無效JSON文本。eval函數将執行惡意的腳本。使用JSON解析器可以防止此類事件。
2. 使用 使用JSON解析器:
2.1 JSON.parse();
JSON parse解析器隻能辨識JSON文本,拒絕所有腳本。提供了本地JSON支援的浏覽器的JSON解析器将遠快于eval函數。預計未來的ECMAScript标準将支援本地 地JSON。
使用格式:
var myObject = JSON.parse(myJSONtext, reviver);
參數:myJSONtext ,要解析的JSON格式字元串
reviver - function可選參數,做為被最終結果的每一級的鍵(key)與值(value)調用。 每個值都将被替換函數的值代替。這可以用來将一般的類改變成僞類的執行個體,或者将日期字元串轉變為日期對象。
myData = JSON.parse(text, function (key, value) {
var type;
if (value && typeof value === 'object') {
type = value.type;
if (typeof type === 'string' && typeof window[type] === 'function') {
return new (window[type])(value);
return value;
});
2.2 JSON.stringify();
JSON stringifier進行反向操作,可以把JavaScript資料結構轉換為JSON文本。JSON不支援循環數
據結構,是以應小心不要為JSON stringifier提供循環結構。
使用格式: 使用格式:
var myJSONText = JSON.stringify(myObject, replacer);
參數:myObject ,要轉為字元串的Javascript object 對象。
replacer,如果stringify函數發現一個帶有toJSON方法的對象,它将執行此方法,并且傳回産生的值。這樣一個對象就可以決定自己的JSON表現。
stringifier方法可以攜帶一個可選的字元串數組。這些字元串被用于選擇包括在JSON文本中的屬性。
stringifier方法可以攜帶一個可選的替代(replacer)函數。它将在結構中每個值的toJSON方法(如果
有的話)後面執行。它将每個鍵與值做為參數傳遞,當然對象要包含這個鍵。值将被stringified傳回。
如果沒有提供數組或替代函數,一個用于忽略被內建的屬性的可選替代函數将被提供。如果想要所有被繼承的屬性,可以提供一個簡單的替換函數:
var myJSONText = JSON.stringify(myObject, function (key, value) {
值在JSON中不代表任何内容,函數與未定義(undefined)被排除在外。
不能确定的數量将被替換為null。為了替代其它的值,可以像下面一樣使用替換(replacer)函數
function replacer(key, value) {
if (typeof value === 'number' && !isFinite(value)) {
return String(value);
開放源代碼的JSON解析器與JSON stringifier可以使用。通過minified可以小于2.5K。
<a href="http://www.json.org/json2.js">http://www.json.org/json2.js</a>
<a href="http://www.crockford.com/javascript/jsmin.html">http://www.crockford.com/javascript/jsmin.html</a>
本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1081603