這是寫給同事參考的範例: 如何在ASP.NET伺服器端承接Javascript以{“p1”:”v1”, "-123":"v2”}方式傳入的Hashtable? 由於鍵值可能出現負號等.NET不允許的屬性名稱字元,加上有哪些鍵值是動態決定,無法事先掌握,故不適合將其轉型成.NET中的類別,轉成Dictionary<string, string>應是較好的解決方法。

引用JSON.NET(PS: JSON.NET現在也可以使用NuGet安裝囉! 按個【讚】)與JavaScriptSerializer,只需幾行Code可以完成轉換。但若用DataContractJsonSerializer,Dictionary<>必須要轉成[{"Key":"...", "Value":"..."}, {"Key":"...", "Value":"..."}]的JSON格式才能順利轉換,在本範例中不推薦使用。

<%@ Page Language="C#" %>
<%@ Import Namespace="Newtonsoft.Json" %>
<%@ Import Namespace="Newtonsoft.Json.Linq" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Runtime.Serialization.Json" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
    if (Request["m"] == "parse")
    {
        //Javascript傳來的JSON字串
        string jsonString = Request["dict"];
        
        
        //方法1 用JSON.NET JObject
        JObject jo = JObject.Parse(jsonString);
        Dictionary<string, string> dict =
            jo.Properties().ToDictionary(
                p => p.Name,
                p => (string)p.Value
        );
        DumpDictionary("JSON.NET 1", dict);
 
        //方法2 用JSON.NET直接轉Dictionary<string, string>
        dict =
            JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
        DumpDictionary("JSON.NET 2", dict);
 
        //方法3 使用JavaScriptSerializer.Deserialize
        JavaScriptSerializer jss = new JavaScriptSerializer();
        dict = (Dictionary<string, string>)
            jss.Deserialize(jsonString, typeof (Dictionary<string, string>));
        DumpDictionary("JavaScriptSerializer", dict);
 
        //DataContractJsonSerializer所要求的Dictionary<string, string>格式是
        //[{"Key":"P1", "Value":"很麻煩"}, {"Key":"123", "Value":"不好用"}]
        //無法直接解讀前方傳來的Hashtable JSON字串,所以...
        //決定放過它(也饒了自己),只做個簡單驗證
        jsonString = 
    @"[{""Key"":""P1"", ""Value"":""很麻煩""}, {""Key"":""123"", ""Value"":""不好用""}]";
        
        DataContractJsonSerializer dcs =
            new DataContractJsonSerializer(typeof(Dictionary<string, string>));
        MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonString));
        dict = dcs.ReadObject(ms) as Dictionary<string, string>;
        DumpDictionary("DataContractJsonSerializer", dict);
 
        Response.End();
    }
}
void DumpDictionary(string title, Dictionary<string, string> dict)
{
    Response.Write(title + 
        "\r\n===============================\r\n");
    Response.Write(
        string.Join("\r\n",
                    dict.Select(
                        kv =>
                        string.Format("{0}=>{1}", kv.Key, kv.Value)
                        ).ToArray()));
    Response.Write("\r\n\r\n");
}
</script>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            var hash = {};
            //故意使用C#中不可做為Property名稱的字樣
            hash["P1"] = "V0";
            hash["123"] = "V1";
            hash["1-2"] = "V2";
            hash["中文"] = "V3";
            $.post("HashtableJson.aspx",
                { m: "parse", dict: JSON.stringify(hash) },
                function (r) {
                    alert(r);
                });
        });
    </script>
</head>
<body>
</body>
</html>

執行結果:

JSON.NET 1
===============================
123=>V1
P1=>V0
1-2=>V2
中文=>V3

JSON.NET 2
===============================
123=>V1
P1=>V0
1-2=>V2
中文=>V3

JavaScriptSerializer
===============================
123=>V1
P1=>V0
1-2=>V2
中文=>V3

DataContractJsonSerializer
===============================
P1=>很麻煩
123=>不好用


Comments

Be the first to post a comment

Post a comment