2011年10月18日 星期二

C# 不用自行寫類別,將JSON轉成Dynamic來讀取

記錄一下。

JSON是一個很有趣的東西,在網頁上很方便讀取並解析,先前我也有分享一篇如何使用ASP讀取JSON,但是工作進階了,要我用視窗軟體讀取JSON...

原本我重頭學VB.NET,就是為了使用VB.NET讀取JSON,但我發現網路上關於VB.NET的文章明顯少於C#,於是學了兩個星期,就毅然決然的改學C#...



雖然C#文章多,但是讀取JSON的文章,我大多是有看沒有懂,一邊學一邊找JSON資料,終於在今天可以成功讀取並解析了,以下是我找到的方法。

先準備一份JSON文件
{ "firstName": "John",
 "lastName": "Smith",
 "male": true,
 "age": 25,
 "address": {
 "streetAddress": "21 2nd Street",
 "city": "New York", "state": "NY",
 "postalCode": "10021" },
 "phoneNumber":
 [
 {
 "type": "home",
 "number": "212 555-1234"
 },
 {
 "type": "fax",
 "number": "646 555-4567"
 }
 ]
 }


我的C#原始碼..(是net.framework 4.0的喔)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Web;
using System.Web.Script.Serialization;
using System.IO;
using System.Dynamic;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Collections;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            // Read the file as one string.
            System.IO.StreamReader myFile =  new System.IO.StreamReader("test.json");
            string myString = myFile.ReadToEnd();

            myFile.Close();

         
            string json = myString;

            dynamic dy = ConvertJson(json);

            Console.WriteLine(dy.firstName);
            Console.WriteLine(dy.lastName);
            Console.WriteLine(dy.address.city);
                     
            foreach (var s in dy.phoneNumber[1])
            {
                Console.WriteLine(s);
            }

            Console.Read();

        }
        static dynamic ConvertJson(string json)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
            dynamic dy = jss.Deserialize(json, typeof(object)) as dynamic;
            return dy;
        }

    }
    public class DynamicJsonConverter : JavaScriptConverter
    {
        public override object Deserialize(IDictionary dictionary, Type type, JavaScriptSerializer serializer)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");

            if (type == typeof(object))
            {
                return new DynamicJsonObject(dictionary);
            }

            return null;
        }

        public override IDictionary Serialize(object obj, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override IEnumerable SupportedTypes
        {
            get { return new ReadOnlyCollection(new List(new Type[] { typeof(object) })); }
        }
    }

    public class DynamicJsonObject : DynamicObject
    {
        private IDictionary Dictionary { get; set; }

        public DynamicJsonObject(IDictionary dictionary)
        {
            this.Dictionary = dictionary;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = this.Dictionary[binder.Name];

            if (result is IDictionary)
            {
                result = new DynamicJsonObject(result as IDictionary);
            }
            else if (result is ArrayList && (result as ArrayList) is IDictionary)
            {
                result = new List((result as ArrayList).ToArray().Select(x => new DynamicJsonObject(x as IDictionary)));
            }
            else if (result is ArrayList)
            {
                result = new List

((result as ArrayList).ToArray());

            }


            return this.Dictionary.ContainsKey(binder.Name);

        }

    }

}



執行後就可以看到:

以上。

參考如下:

應該是原始程式的文章:
http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

http://msdn.microsoft.com/zh-tw/library/aa287534(v=vs.71).aspx
http://zh.wikipedia.org/wiki/JSON
http://www.3ppt.com/Design/Csharp/19391.html  (應該是copy第一個參考網址的內容,加以修改。)

沒有留言: