茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1672154 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_60D_00010.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

Dot Net? : [轉貼]C# 產生 JSON 字串的幾種方式整理

發表者 討論內容
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]C# 產生 JSON 字串的幾種方式整理

[C#.net] 產生JSON字串的幾種方式整理

↙部落格忽然多了好多回應有關Json的文章,讓我想起我還沒寫怎麼產生JSON字串XD

這邊就以 Google API裡有段JSON字串當作練習怎麼產生:

image

以下整理幾種我見過的方式(個人推薦的放在最後^_^)

1. 字串拼接

最麻煩的方式,可讀性也差,若遇到Boolean型別的變數要記得轉小寫




protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
string collapse_key = "score_update";
int time_to_live = 108;
bool delay_while_idle = true;
string score = "4x8";
string time = "15:16.2342";
List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
//開始拼接字串
StringBuilder sb = new StringBuilder();
sb.AppendLine("{");
sb.AppendLine("\"collapse_key\":\""+collapse_key+"\",");
sb.AppendLine("\"time_to_live\":"+time_to_live+",");
sb.AppendLine("\"delay_while_idle\":"+delay_while_idle.ToString().ToLower()+",");
sb.AppendLine("\"data\":{");
sb.AppendLine("\"score\":\""+score+"\",");
sb.AppendLine("\"time\":\""+time+"\"");
sb.AppendLine("},");
sb.AppendLine("\"registration_ids\":[");
foreach (string item in registration_ids)
{
sb.Append("\""+item+"\",");
}
sb = new StringBuilder(sb.ToString().TrimEnd(','));//移除最後一個「,」字元
sb.AppendLine("]");
sb.AppendLine("}");
//輸出結果
Response.Write(sb.ToString());
}
}

↑所以很多人會尋找第三方套件來處理吧

以下便介紹 Json.net,因為威力太強大了~

image

有了Json.net後就可以使用Json.net的函數產生JSON字串

2. 使用 JsonTextWriter

用法很像XmlTextWriter,寫起來有點囉嗦,平常工作我不會用這個



protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
string collapse_key = "score_update";
int time_to_live = 108;
bool delay_while_idle = true;
string score = "4x8";
string time = "15:16.2342";
List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
//要輸出的變數
StringWriter sw = new StringWriter();
//建立JsonTextWriter
JsonTextWriter writer = new JsonTextWriter(sw);
writer.WriteStartObject();
writer.WritePropertyName("collapse_key"); writer.WriteValue(collapse_key);
writer.WritePropertyName("time_to_live"); writer.WriteValue(time_to_live);
writer.WritePropertyName("delay_while_idle"); writer.WriteValue(delay_while_idle);
writer.WritePropertyName("data");
writer.WriteStartObject();
writer.WritePropertyName("score"); writer.WriteValue(score);
writer.WritePropertyName("time"); writer.WriteValue(time);
writer.WriteEndObject();
writer.WritePropertyName("registration_ids");
writer.WriteStartArray();
foreach (string item in registration_ids)
{
writer.WriteValue(item);
}
writer.WriteEndArray();
writer.WriteEndObject();
//輸出結果
Response.Write(sw.ToString());
}
}

3. 使用JObject匿名物件

比起JsonTextWriter簡化了許多,不過大概是每個Property和值都要再寫一次建構子名稱,我覺得還是有點麻煩



protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
string collapse_key = "score_update";
int time_to_live = 108;
bool delay_while_idle = true;
string score = "4x8";
string time = "15:16.2342";
List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
//JObject匿名物件
JObject obj = new JObject(
new JProperty("collapse_key",collapse_key),
new JProperty("time_to_live",time_to_live),
new JProperty("delay_while_idle",delay_while_idle),
new JProperty("data",
new JObject(
new JProperty("score",score),
new JProperty("time",time))),
new JProperty("registration_ids",registration_ids)
);
//序列化為JSON字串並輸出結果
Response.Write(JsonConvert.SerializeObject(obj,Formatting.Indented));
}
}

那有沒有寫起來直覺,程式碼又短少的方式呢?

請看以下兩個

4. 物件序列化

這個要先知道輸出的json字串長什麼樣子

貼到 http://json2csharp.com/去產生類別程式碼

image

然後



protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
string collapse_key = "score_update";
int time_to_live = 108;
bool delay_while_idle = true;
string score = "4x8";
string time = "15:16.2342";
List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
//建立物件,塞資料
RootObject root = new RootObject();
root.collapse_key = collapse_key;
root.time_to_live = time_to_live;
root.delay_while_idle = delay_while_idle;
Data data = new Data();
root.data = data;
root.data.score = score;
root.data.time = time;
root.registration_ids = registration_ids;
//物件序列化
string strJson = JsonConvert.SerializeObject(root, Formatting.Indented);
//輸出結果
Response.Write(strJson);
}
}

或使用物件初始化方式塞值



protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
string collapse_key = "score_update";
int time_to_live = 108;
bool delay_while_idle = true;
string score = "4x8";
string time = "15:16.2342";
List<string> registration_ids = new List<string>() { "4","8","15","16","23","42"};
//建立物件,塞資料
RootObject root = new RootObject()
{
collapse_key = collapse_key,
time_to_live = time_to_live,
delay_while_idle = delay_while_idle,
data = new Data()
{
score = score,
time=time
},
registration_ids = registration_ids
};
//物件序列化
string strJson = JsonConvert.SerializeObject(root, Formatting.Indented);
//輸出結果
Response.Write(strJson);
}
}

使用物件初始化方式塞值看起來直覺多了

不過為了物件序列化還要特地宣告類別,這…倒不如使用Linq吧

5.用Linq+匿名物件寫法 直接組JSON

這招在Json.net的官方文件有範例(用JObject.FromObject的那個): http://james.newtonking.com/projects/json/help/html/CreatingLINQtoJSON.htm

但只有範例,沒寫為什麼Linq要那樣寫,誰看得懂阿XD

要用Linq直接組JSON

大概把握幾點:

Json Object:Json字串用大括號{}表示,Linq也是用大括號{}表示

Json Object的Name(Key、Property):Json字串在兩個雙引號””裡寫一個英文單字,Linq就直接寫英文單字即可

Json Array:Json字串用中括號[]表示,Linq就用from o in XXX select o,這種回傳IEnumerable的寫法(如果JSON字串是物件陣列的話就用from o in XXX select new {欄位1=YYY}這種形式)

Json Value:Linq就看Json字串填什麼值就跟著填什麼值




protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//Get Method
{
//準備資料
List<string> registration_ids = new List<string>() { "4", "8", "15", "16", "23", "42" };
//用Linq直接組
var result = new
{
collapse_key = "score_update",
time_to_live = 108,
delay_while_idle = true,
data = new{
score ="4x8",
time = "15:16.2342"
},
registration_ids = from s in registration_ids
select s
};
//序列化為JSON字串並輸出結果
Response.Write(JsonConvert.SerializeObject(result));
}
}

請看圖示解說↓

image

由於Linq支援DataTable的查詢,所以再難的JSON格式都組得出來,不用再跑for迴圈寫一堆Code,開發速度大幅提昇

以下截自實務上的一段Code(有做了一點修改)



DataTable dt = new DataTable();//撈出一張資料表的所有數據(這個表類似北風資料庫的員工資料表,有階層關係)
DataTable dtDetail = new DataTable();//上一張表的一對多明細表
var firstLevel = dt.Select("pid is NULL");//第一層數據
var result = new
{
Info = new
{
Level1 = from a in firstLevel
join b in dt.AsEnumerable() on a.Field<int>("id") equals b.Field<int?>("pid") into secondLevel
select new
{
Title = a.Field<string>("Title"),
Level2 = secondLevel.Select(c => new
{
Title = c.Field<string>("Title"),
Photos = from s in secondLevel
join uu in dtDetail.AsEnumerable() on s.Field<int>("id") equals uu.Field<int>("id")
where s.Field<int>("id") == c.Field<int>("id")
select new
{
PhotoID = uu.Field<string>("PhotoID"),
PhotoTitle = uu.Field<string>("PhotoTitle")
}
})
}
}
};

※不過要注意對於寫的人是寫很快,後人維護會有閱讀困難的可能

最後附上一張比較圖

image

2012.11.09 追記

最後一個方法,直接使用Linq產生Json字串有個缺點要提一下

Linq匿名型別的屬性無法給null值,如下圖

image



原文出處: [C#.net] 產生JSON字串的幾種方式整理 - The blog of typewriter職人- 點部落
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]Unity C# Json 編碼、解碼 (使用 Json.Net)

Unity C# Json 編碼、解碼 (使用 Json.Net)

請先將 Newtonsoft.Json.dll 檔案放到 Unity 專案底下,即可開始使用。

using UnityEngine;
using System.Collections;
using Newtonsoft.Json;

public class Book
{
         public int ID { get; set; }
         public string Name { get; set; }
         public string Author { get; set; }
}

public class Test : MonoBehaviour
{
         void
Start ()
        {
                Book book = new Book ();
                book.ID = 1;
                book.Name = "Push Loli ( Getting Started )";
                book.Author = "Alice";

                 // Json Encoding
                string output = JsonConvert.SerializeObject (book);
                print (output);

                
// Json Decoding
                Book book2 = JsonConvert.DeserializeObject<Book> (output);
                print ( "ID : " + book2.ID);
                print ( "Name : " + book2.Name);
                print ( "Author : " + book2.Author);

        }
}

 輸出結果:

Unity - Untitled - JsonTest - PC, Mac & Linux Standalone  

 


 高級版:

 


using UnityEngine;
using System.Collections;
using Newtonsoft.Json;
using System.Collections.Generic;

public class Book
{
       public int ID ;
        public string Name ;
        public string Author;
        public List< string> ListData = new List< string> ();
}

public class RootLibrary
{
       
// Value name (Library) is Json root "Name".
        public List<Book> Library = new List<Book> ();
}

public class Test : MonoBehaviour
{
        void Start ()
       {
               // Json Path : Library.book
              Book book = new Book ();
              book.ID = 1;
              book.Name = "Unity Book";
              book.Author = "Bee"
;
              book.ListData.Add ( "Box");
              book.ListData.Add ( "Banana");
              book.ListData.Add ( "Ball");

               // Json Path : Library.book2
              Book book2 = new Book ();
              book2.ID = 2;
              book2.Name = "C# Book";
              book2.Author = "God"
;
              book2.ListData.Add ( "Man");
              book2.ListData.Add ( "Boy");
              book2.ListData.Add ( "Girl");

               // Json Path : Library.book3
              Book book3 = new Book ();
              book3.ID = 3;
              book3.Name = "Loli Book";
              book3.Author = "Alice"
;
              book3.ListData.Add ( "Cat");
              book3.ListData.Add ( "Dog");
              book3.ListData.Add ( "Apple");

               // Json Path : Library (Root)
              RootLibrary lib = new RootLibrary ();
              lib.Library.Add (book);
              lib.Library.Add (book2);
              lib.Library.Add (book3);

              
// Json Encoding
               string output = JsonConvert.SerializeObject (lib);
              print (output);

               //--------------------------------------------------------------

              // Json Decoding
              RootLibrary _lib = JsonConvert.DeserializeObject<RootLibrary> (output);

               foreach (Book _book in _lib.Library) {
                     print (
"----------------------------------");
                     print ( "ID : " + _book.ID);
                     print ( "Name : " + _book.Name);
                     print ( "Author : " + _book.Author);
                      for ( int i =0; i<_book.ListData.Count; i++) {
                            print ( "ListData [ " + i + " ] : "
+ _book.ListData [i]);
                     }
              }
       }
}

輸出結果(第一行因為太長了所以被切斷,所以我自行排版後並上傳文字結果):


{
"Library":
       [
              {
                     "ID":1,
                     "Name":"Unity Book",
                     "Author":"Bee",
                     "ListData":["Box","Banana","Ball"]
              },
              {
                     "ID":2,
                     "Name":"C# Book",
                     "Author":"God",
                     "ListData":["Man","Boy","Girl"]
              },
              {
                     "ID":3,
                     "Name":"Loli Book",
                     "Author":"Alice",
                     "ListData":["Cat","Dog","Apple"]
              }
       ]
}

  Unity - Untitled - JsonTest - PC, Mac & Linux Standalone  

 


 Json 查詢: 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class RootLibrary
{
     public string Type;
}

public class Test : MonoBehaviour
{
     void
Start ()
    {
        RootLibrary lib = new RootLibrary ();
        lib.Type = "BookLibrary";

         // Json Encoding
        string output = JsonConvert.SerializeObject (lib);
        print (output);

         //--------------------------------------------------------------

         // Json Decoding
        JObject obj = JsonConvert.DeserializeObject<JObject> (output);
        print (obj.GetValue( "Type"
));
        print (obj[ "Type"]);
    }
}

 

  輸出結果:

  Unity - Untitled - JsonTest - PC, Mac & Linux Standalone  


原文出處:Unity C# Json 編碼、解碼 (使用 Json.Net) @ 彥霖 實驗筆記 :: 痞客邦 PIXNET ::
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]C# 的 Json 序列化和反序列化(Json.NET)

C# 的 Json 序列化和反序列化(JSON.NET)

On 2012/06/27, in C#, by Allen J

Json 是一種很 簡潔的資料格式
經常使用在資料傳輸
例如 Facebook API、Google Map API 等

JSON – 維基百科

JSON(Javascript Object Notation) 是一種輕量級的資料交換語言,以文字為基礎,且易於讓人閱讀。儘管JSON是在Javascript的一個子集,但JSON是獨立於語言的文本格式,並且採用了類似於C語言家族的一些習慣。

.NET Framework 支援 Json

C# 想當然會支援 Json 的轉換
不過在 .NET Framework 3.5 之後才有原生的類別庫
分別為
DataContractJsonSerializerJavaScriptSerializer
在操作上也很 麻煩
筆者選擇使用第三方類別庫 Json.NET
使用容易又不會有 .NET Framework 版本限制

JSON.NET 介紹

JSON.NET 是一個 高效能功能強大的第三方類別庫
支援多種格式的轉換及使用簡單

Features

  • Flexible JSON serializer for converting between .NET objects and JSON

  • LINQ to JSON for manually reading and writing JSON
  • High performance, faster than .NET’s built-in JSON serializers
  • Write indented, easy to read JSON
  • Convert JSON to and from XML
  • Supports .NET 2, .NET 3.5, .NET 4, Silverlight, Windows Phone and Windows 8 Metro.

效能

JSON.NET 與 .NET Framework 原生類別庫的效能比較

簡潔程式碼

可以透過 NuGet 安裝或直接下載類別庫
程式碼也簡單的不得了



//將物件轉成 Json 字串(序列化)
string output = JsonConvert.SerializeObject(book);
//將 Json 字串轉成物件(反序列化)
Book book = JsonConvert.DeserializeObject<Book>(output);

有一個功能筆者覺得是滿重要的
一般來說物件的 全部屬性都會被序列化
不過 JSON.NET 可以 指定物件屬性是否被序列化
例如 BOOK 類別的 Date 屬性
並不想被序列化成字串
可以使用 [JsonIgnore] 去忽略



[JsonObject(MemberSerialization.OptOut)]
public class Book
{
public int ID { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string Author { get; set; }
}

或是使用 [JsonProperty] 去加入序列化



[JsonObject(MemberSerialization.OptIn)]
public class Book
{
[JsonProperty]
public int ID { get; set; }
[JsonProperty]
public string Name { get; set; }
public string Author { get; set; }
}

備註


因 C# 是 強型別的語言
所以要先 建立類別去產生物件
或是讓字串反序列化時 對應到類別



public class Book
{
public int ID { get; set; }
public string Name { get; set; }
public string Author { get; set; }
}

範例程式碼



Book book = new Book();
book.ID = 1;
book.Name = "百科全書";
book.Author = "無名氏";
string output = JsonConvert.SerializeObject(book);
Response.Write(output + "<br />");
Book book2 = JsonConvert.DeserializeObject<Book>(output);
Response.Write("ID = " + book2.ID + "<br />");
Response.Write("Name = " + book2.Name + "<br />");
Response.Write("Author = " + book2.Author + "<br />");

執行結果

參考資料:
Json.NET
c# 解析JSON的幾種方法
c#中的Json的序列化和反序列化
[C#]Json.NET – A high performance Json library



原文出處:C# 的 Json 序列化和反序列化(Json.NET) | Allen J
冷日
(冷日)
Webmaster
  • 註冊日: 2008/2/19
  • 來自:
  • 發表數: 15771
[轉貼]利用 JSON.net 實現 DataTable 轉 JSON 字串、JSON 字串轉 DataTable

[ASP.net WebForm] 利用JSON.net 實現 DataTable轉JSON字串、JSON字串轉DataTable (程式碼短少)

想不到這篇文章在Google搜尋那麼前面,順便宣傳一下另一篇: [C#.net] 產生JSON字串的幾種方式整理

Json.NET 是一套在Server端處理JSON格式資料的好套件

基本操作在最底下文章已提及

這邊要紀錄的是DataTable和JSON字串之間的互轉(而且Code很少)

要使用Json.NET的話,先到官網: http://json.codeplex.com/

image

下載紅框處


解壓縮後把Bin\Net資料夾底下的Newtonsoft.Json.dll放到Web Site專案的Bin目錄下即完成加入參考

再來看這次要實驗的資料集

image

接著開始寫程式

在.aspx設計畫面



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Literal ID="li_showData" runat="server" /><hr />
<asp:Button Text="把DataTable轉成JSON字串" ID="btn_DataTableToJSONstr" runat="server"
OnClick="btn_DataTableToJSONstr_Click" />
<asp:Button Text="把JSON字串轉成DataTable" ID="btn_JSONstrToDataTable" runat="server"
OnClick="btn_JSONstrToDataTable_Click" /><hr />
<!--JSON字串轉成DataTable後要跟GridView1做DataBind()-->
<asp:GridView runat="server" ID="GridView1" />
</form>
</body>
</html>

Code-Behind

DataTable互轉JSON字串,重點只要一行程式碼就夠了



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
/*要引用以下命名空間*/
using System.Data;
using System.Data.SqlClient;
/*Json.NET相關的命名空間*/
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public partial class _Default : System.Web.UI.Page
{
//DB連線字串
string connStr = @"Data Source=.\sqlexpress;Initial Catalog=NorthwindChinese;Integrated Security=True";
string sql = @"Select CategoryID,CategoryName,Description from Categories
Where CategoryID Between 1 And 5"
;
protected void Page_Load(object sender, EventArgs e)
{
}
/// <summary>
///
依據SQL語句,回傳DataTable物件
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
private DataTable queryDataTable(string sql)
{
DataSet ds = new DataSet();
using (SqlConnection conn = new SqlConnection(this.connStr))
{
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds);
}
return ds.Tables.Count > 0 ? ds.Tables[0] : new DataTable();
}
//把DataTable轉成JSON字串
protected void btn_DataTableToJSONstr_Click(object sender, EventArgs e)
{
//得到一個DataTable物件
DataTable dt = this.queryDataTable(this.sql);
//將DataTable轉成JSON字串
string str_json = JsonConvert.SerializeObject(dt, Formatting.Indented);
//JSON字串顯示在畫面上
li_showData.Text = str_json;
}
//把JSON字串轉成DataTable或Newtonsoft.Json.Linq.JArray
protected void btn_JSONstrToDataTable_Click(object sender, EventArgs e)
{
//Newtonsoft.Json.Linq.JArray jArray =
// JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JArray>(li_showData.Text.Trim());
//或
DataTable dt = JsonConvert.DeserializeObject<DataTable>(li_showData.Text.Trim());
//GridView1顯示DataTable的資料
//GridView1.DataSource = jArray; GridView1.DataBind();
GridView1.DataSource = dt; GridView1.DataBind();
}
}

執行結果:

image

使用ADO.net Entity Framework也可以輕鬆互轉JSON字串



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
/*自行引用命名空間*/
using NorthwindChineseModel;
using Newtonsoft.Json;
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
//把IQueryable轉成JSON字串
protected void btn_EntitySetToJSONstr_Click(object sender, EventArgs e)
{
using (NorthwindChineseEntities entities = new NorthwindChineseEntities())
{
IQueryable categories = from c in entities.Categories
where c.CategoryID >= 1 && c.CategoryID <= 5
select new { c.CategoryID, c.CategoryName, c.Description };
string str_json = JsonConvert.SerializeObject(categories, Formatting.Indented);
//顯示JSON字串
li_showData.Text = str_json;
}
}
//把JSON字串轉成Newtonsoft.Json.Linq.JArray
protected void btn_JSONstrToEntitySet_Click(object sender, EventArgs e)
{
Newtonsoft.Json.Linq.JArray jArry = JsonConvert.DeserializeObject < Newtonsoft.Json.Linq.JArray>(li_showData.Text.Trim());
GridView1.DataSource = jArry; GridView1.DataBind();
}
}

另外

要閱讀JSON字串的話,個人推薦 Online JSON Viewer

把JSON字串貼到Text頁籤的畫面上,可以再按Format排版

image

也可以再按Viewer進一步察看資料

image

如果JSON格式不符的話,會跳出一個alert訊息


image

算是輔助Debug的工具

本文章的 專案包

2011.12.01 追加

既然都講到Server端的JSON字串,順便把JSONP字串也補完



if(!string.IsNullOrEmpty(Request.QueryString["callback"]))
{
str_json = Request.QueryString["callback"] + "("+str_json+");";
}//這樣出來的str_json就是JSONP字串了

參考資料: How to convert datatable to json string using json.net?

衍伸閱讀文章: CODE-使用JSON.NET處理動態物件屬性

好用的JSON Library:Json.NET


原文出處: [ASP.net WebForm] 利用JSON.net 實現 DataTable轉JSON字串、JSON字串轉DataTable (程式碼短少) - The blog of typewriter職人- 點部落
前一個主題 | 下一個主題 | 頁首 | | |



Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|