JavaScriptSerializer類 對象序列化為JSON,JSON反序列化為對象


JavaScriptSerializer 類由異步通信層內部使用,用於序列化和反序列化在瀏覽器和 Web 服務器之間傳遞的數據。說白了就是能夠直接將一個C#對象傳送到前台頁面成為javascript對象。要添加System.Web.Extensions.dll的引用。該類位於System.Web.Script.Serialization命名空間下。

一、屬性

MaxJsonLength 獲取或設置 JavaScriptSerializer 類接受的 JSON 字符串的最大長度。
RecursionLimit 獲取或設置用於約束要處理的對象級別的數目的限制。

二、方法

ConvertToType<(Of <(T>)>) 將給定對象轉換為指定類型。
Deserialize<(Of <(T>)>) 將指定的 JSON 字符串轉換為 T 類型的對象。
DeserializeObject 將指定的 JSON 字符串轉換為對象圖。
RegisterConverters 使用 JavaScriptSerializer 實例注冊自定義轉換器。
Serialize 已重載。 將對象轉換為 JSON 字符串。

 給個示例,主要就是了解了一下Serialize與Deserialize兩個方法,控制器代碼:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult GetJson()
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            Person p = new Person(1, "張飛", 20);
            string json = jss.Serialize(p); //序列化成JSON
            Person p1 = jss.Deserialize<Person>(json);  //再反序列化為Person對象    注意此方法要求目標類有無參構造函數
            //return Json(json, "text/json");     //很好用,但是返回的終歸是字符串,返回到前台要解析一下才能變成javascript對象。
            return Json(new { Id = p1.Id, Name = p1.Name, Age = p1.Age }, "text/json");//如果這樣寫,返回到javascript中是不用再解析的,直接就是javascript對象
        }

    }
    public class Person
    {
        public Person()
        { }
        public Person(int id, string name, int age)
        {
            this.Id = id;
            this.Name = name;
            this.Age = age;
        }
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

前台HTML代碼:

<html>
<head>
    <title>javascriptSerializer類測試</title>
    <script src="/jQuery.1.8.3.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $(":button").click(function () {
                $.ajax({
                    url: "/Home/GetJson",
                    dataType: "json",
                    type: "post",
                    success: function (response) {
//                        var data = JSON.parse(response);
//                        $("#Id").text(data.Id);
//                        $("#Name").text(data.Name);
//                        $("#Age").text(data.Age);

                        $("#Id").text(response.Id);
                        $("#Name").text(response.Name);
                        $("#Age").text(response.Age);
                    }
                })
            })
        })
    </script>
</head>
<body>
    <ul>
        <li id="Id"></li>
        <li id="Name"></li>
        <li id="Age"></li>
    </ul>
    <input type="button" value="確認" />
</body>
</html>

   試下4個基礎方法與屬性

class Program
    {
        static void Main(string[] args)
        {
            // 方法 
            // RegisterConverters 使用 JavaScriptSerializer 實例注冊自定義轉換器。  
            //屬性
            // RecursionLimit 獲取或設置用於約束要處理的對象級別的數目的限制。 

            JavaScriptSerializer jss = new JavaScriptSerializer();
            Console.WriteLine(jss.MaxJsonLength);   //默認接受最大的長度是 2097152    這個是接受JSON字符串的最大長度,超長會有什么后果呢?試下
            jss.MaxJsonLength = 1;

            Person p = new Person(1,"關羽",21);
            //string json = jss.Serialize(p);     //將對象序列化成Json字符串    //此處報異常使用 JSON JavaScriptSerializer 進行序列化或反序列化時出錯。字符串的長度超過了為 maxJsonLength 屬性設置的值。

            jss.MaxJsonLength = 2097152;
            
            //序列化
            string json = jss.Serialize(p); 
            Console.WriteLine(json);    //輸出 {"Id":1,"Name":"關羽","Age":21}`這就是Json格式了

            //反序列化Deserialize
            Person p2 = jss.Deserialize<Person>("{\"Id\":1,\"Name\":\"關羽\",\"Age\":21}");
            Console.WriteLine(p2.Id + " " + p2.Name + " " + p2.Age);    //輸出 1 關羽 21
            //Deserialize的非泛型寫法
            Person p3 = jss.Deserialize("{\"Id\":1,\"Name\":\"關羽\",\"Age\":21}",typeof(Person)) as Person;  //注意這個方法返回的是object類,因此要強制轉換成Person類
            Console.WriteLine(p3.Id + " " + p3.Name + " " + p3.Age);    //同樣輸出 1 關羽 21

            object obj = jss.DeserializeObject("{\"Id\":1,\"Name\":\"關羽\",\"Age\":21}");    //將Json字符轉換為Object類型
            //Person p4 = obj as Person;    //此行代碼轉為的p4為null
            Person p4 = jss.ConvertToType<Person>(obj);     //尼瑪,原來這個方法是這樣用的,知道DeserializeObject轉換會為null所以另外寫一個嗎
            Console.WriteLine(p4.Name);     //輸出關羽
            //非泛型版本
            Person p5 = jss.ConvertToType(obj,typeof(Person)) as Person;
            Console.WriteLine(p5.Name);     //輸出關羽

            Console.ReadKey();
        }
    }

  實現自定義轉換器

  將指定的數據類型序列化為Json。Serialize方法是個遞歸方法,會遞歸地序列化對象的屬性,因此在序列化一個復雜對象(比如DataTable)時往往會出現“循環引用”的異常,這時候就需要針對復雜類型自定義一個轉換器。下面是DataTable的轉換器,原理是把DataTable轉換成一個字典列表后再序列化:

所有自定義的轉換器都要繼承於JavaScriptConverter並實現Serialize、Deserialize方法和SupportedTypes屬性,其中SupportedTypes屬性用於枚舉此轉換器支持的類型。

    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Id");
            dt.Columns.Add("Name");
            dt.Columns.Add("Age");
            dt.Rows.Add(1, "關羽", 21);
            dt.Rows.Add(2, "劉備", 22);
            dt.Rows.Add(3, "張飛", 20);

            JavaScriptSerializer jss = new JavaScriptSerializer();
            //注冊轉換器的方法,用於復雜轉換  除了實現還需要注冊到JavaScriptSerializer
            jss.RegisterConverters(new JavaScriptConverter[] { new DataTableConverter() });

            string strJson = jss.Serialize(dt);
            Console.WriteLine(strJson);
            //輸出 {"Rows":[{"Id":"1","Name":"關羽","Age":"21"},{"Id":"2","Name":"劉備","Age":"22"},{"Id":"3","Name":"張飛","Age":"20"}]}

            Console.ReadKey();
        }
    }

    /// <summary>
    /// DataTable JSON轉換類
    /// </summary>
    public class DataTableConverter : JavaScriptConverter
    {
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            DataTable dt = obj as DataTable;
            Dictionary<string, object> result = new Dictionary<string, object>();

            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();

            foreach (DataRow dr in dt.Rows)
            {
                Dictionary<string, object> row = new Dictionary<string, object>();
                foreach (DataColumn dc in dt.Columns)
                {
                    row.Add(dc.ColumnName, dr[dc.ColumnName]);
                }
                rows.Add(row);
            }

            result["Rows"] = rows;

            return result;
        }

        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 獲取本轉換器支持的類型
        /// </summary>
        public override IEnumerable<Type> SupportedTypes
        {
            get { return new Type[] { typeof(DataTable) }; }
        }
    }

限制序列化的層次

class Program
    {
        static void Main(string[] args)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            Console.WriteLine(jss.RecursionLimit);  //默認的序列化層次是100

            Person p1 = new Person(1, "劉備", 24);
            p1.p = new Person(2, "關羽", 23);
            p1.p.p = new Person(3, "張飛", 21);

            string strJson = jss.Serialize(p1);
            Console.WriteLine(strJson);
            //輸出 {"Id":1,"Name":"劉備","Age":24,"p":{"Id":2,"Name":"關羽","Age":23,"p":{"Id":3,"Name":"張飛","Age":21,"p":null}}}

            //現在將層次減少到1
            jss.RecursionLimit = 1;
            string strJson2 = jss.Serialize(p1);//這行代碼是報異常的,顯示已超出 RecursionLimit。 這就是這個屬性的作用
            

            //最后再來說一個特性,比如如果我有某一個屬性不希望它序列化,那么可以設置添加
            

            Console.ReadKey();
        }
    }

    public class Person
    {
        public Person()
        { }

        public Person(int id, string name, int age)
        {
            this.Id = id;
            this.Name = name;
            this.Age = age;
        }

        public int Id { get; set; } 
        public string Name { get;  set; } 
        public int Age { get; set; } 
        //里面嵌套一個Person
        public Person p { get; set; }
    }

[ScriptIgnore]禁止某屬性序列化 

class Program
    {
        static void Main(string[] args)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            Person p = new Person(1,"劉備",24);
            Console.WriteLine(jss.Serialize(p));
            File.WriteAllText(@"D:\123.txt", jss.Serialize(p));  //輸出 {"Id":1,"Age":24}
            Console.ReadKey();
        }
    }

    public class Person
    {
        public Person()
        { }

        public Person(int id, string name, int age)
        {
            this.Id = id;
            this.Name = name;
            this.Age = age;
        }

        public int Id { get; set; } 
       [ScriptIgnore] public string Name { get; set; } 
        public int Age { get; set; }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM