亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

.Net深入實戰系列—JSON序列化那點事兒

2019-11-14 13:59:59
字體:
來源:轉載
供稿:網友

        當前主流的序列化JSON字符串主要有兩種方式:javaScriptSerializer及Json.net(Nuget標識:Newtonsoft.Json)。JavascriptSerializer是微軟官方提供的一種方法,所以如果你用的是asp.net mvc,在Action中如果你返回的語句寫的是”return Json(xxx);“,其實你用的就是JavaScriptSerializer方式?,F在更多的人選擇的是Json.net,因為它為用戶提供了更加清晰地使用體驗,清晰在哪?本文主要就是帶你走進它們的世界。

JavaScriptSerializer與Json.net

序列化

我們先定義一個測試用的簡單類--Person:

  public class Person    {        public string Name;        public int Age;        public Guid TokenId;        public DateTime RegTime;        public Person Child;        public Person Friend;    }

類中的成員僅用來區分不同的變量類型。我們分別以JavaScriptSerializer和Json.net來序列化:

var person = new Person{    Age = 28,    Name = "李玉寶<yubaolee:>",//故意添加特殊字符    RegTime = DateTime.Now,    TokenId = Guid.NewGuid(),    Child = new Person    {        Age = 1,        Name = "baby",        RegTime = DateTime.Now,        TokenId = Guid.NewGuid()    }};  //注意這里面的Friend沒有賦值,默認為空JavaScriptSerializer serializer = new JavaScriptSerializer();var jsstr = serializer.Serialize(person);                //使用JavaScriptSerializer序列化string newtonstr = JsonConvert.SerializeObject(person);  //使用Json.net序列化

JavaScriptSerializer序列化是先生成一個對象,然后調用它的成員函數Serialize進行序列化;

Json.net直接使用提供的靜態成員JsonConvert.SerializeObject進行序列化;

兩者使用都比較簡單,Json.net調用起來方便那么一丟丟!我們來看一下控制臺輸出結果:

image

上面綠色為JavaScriptSerializer的結果,下面黃色背景為Json.net的結果,這里需要注意幾個地方:

1、 JavaScriptSerializer序列化后的時間格式:"http://Date(1441813200214)//" 表示的是1970年1月1日(DateTime的最小值)到date實際表示的日期之差的總毫秒數。通常我們需要把它轉成標準的時間格式。可以用下面的方法進行字符串處理:

jsstr = Regex.Replace(jsstr, @"http:///Date/((/d+)/)///", match =>{    DateTime dt = new DateTime(1970, 1, 1);    dt = dt.AddMilliseconds(long.Parse(match.Groups[1].Value));    dt = dt.ToLocalTime();    return dt.ToString("yyyy-MM-dd HH:mm:ss");});

處理完成后的效果:

image

當然,你還可以通過使用繼承JavaScriptConverter的方式,下面反序列化中會具體提及到這種方式。

Json.net默認生成的日期也不方便客戶端閱讀,需要簡單的處理一下:

string newtonstr = JsonConvert.SerializeObject(p, Formatting.Indented,                new IsoDateTimeConverter() {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"});

2、JavaScriptSerializer序列化會對特殊字符(如<>等)進行編碼,比如上面的/u003c /u003e,很多人看到這個的時候,第一感覺就是太扯蛋了,接下來就是各種百度,怎么把這個轉成正常的”<>”。實際上你不用做任何操作,這是標準的JS編碼方式,前端會自行處理這個問題。比如:

<script type="text/javascript">    var str = 'yubaolee <yubaolee>'    var str2 = 'yubaolee /u003cyubaolee/u003e';    alert(str == str2);  //結果為true</script>

附:如果你真的不明白/u003c這到底是個什么玩意,請移步:字符編碼。

 

從上面兩點可以看出,JavaScriptSerializer序列化出來的JSON字符串容易給人造成一些困惑,而Json.net完全沒有上面的兩種情況處理。所以現在很多人都在用Json.net,但從Html標準的角度上來看,JavaScriptSerializer序列化出來的結果更符合Html的要求。不過為了操作習慣,還是建議使用Json.net。

反序列化

我們分別用兩種方式對上面已經成功序列化的兩個字符串進行反序列化:

//對JavaScriptSerializer生成的字符串進行反序列化//使用JavaScriptSerializer方式var jsperson = serializer.Deserialize<Person>(jsstr);//使用Json.net方式var newtonperson = JsonConvert.DeserializeObject<Person>(jsstr);//對Json.net生成的字符串進行反序列化var jsperson2 = serializer.Deserialize<Person>(newtonstr);var newtonperson2 = JsonConvert.DeserializeObject<Person>(newtonstr);

通過運行會發現4個反序列化代碼都能正常運行,而不是像以前某些前輩說的,JavaScriptSerializer序列化的串只能用它反序列化,Json.net序列化的串只能用Json.net來反序列化。

上面反序列化的字符串是程序生成的,能正常反序列化不足為奇。但通常我們要反序列化的字符串是客戶提交到服務器上面來的串,他們通常是不完整的,或有些還會出現類型不符的情況。比如:

string noChildStr =    "{/"Name/":/"李玉寶<yubaolee:>/"," +    "/"Age/":28," +    "/"RegTime/":/"2015-09-11 00:10:48/"," +    "/"Friend/":null}";  var jsperson = new JavaScriptSerializer().Deserialize<Person>(noChildStr);var newtonperson = JsonConvert.DeserializeObject<Person>(noChildStr);

注意這個字符串中,沒有TokenId,沒有Child,而且Friend為null??匆豢唇Y果:

image

兩個都很智能嘛!解析的結果全部是我們想要的內容。但如果像下面這樣呢?

string noChildStr =    "{/"Name/":/"李玉寶<yubaolee:>/"," +    "/"Age/":28," +    "/"RegTime/":/"2015-09-11 00:10:48/"," +    "/"Friend/":null," +    "/"TokenId/":null}";  //注意這個TokenId為空

在運行的時候,程序會直接報錯。

image

錯誤的內容很容易理解,因為我們把一個null賦值給Guid類型,肯定會出錯。在實際的項目操作過程中還有可能出現把一個內容為空的字符串傳給Datetime類型,把一個數字傳給GUID等各種參數傳遞的問題,關鍵是我們還要來處理它們,而不能使程序直接報錯崩潰。

1、在JavaScriptSerializer中有一個JavaScriptConverter可以來處理這些問題,它是用來實現JSON序列化中自定義類型的處理。比如下面的代碼,就是處理把一個null賦值給Guid的情況:

public class PersonJsConverter : JavaScriptConverter{    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)    {        Person person = new Person();        object value = null;        if (dictionary.TryGetValue("TokenId", out value) && value != null)            person.TokenId = (Guid) value;        //其他字段略...                return person;    }    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)    {        Dictionary<string, object> dic = new Dictionary<string, object>();        var node = obj as Person;        if (node == null)            return null;        if (!string.IsNullOrEmpty(node.Name))            dic.Add("Name", node.Name);        //其他字段略...        return dic;    }    public override IEnumerable<Type> SupportedTypes    {        get        {            return new Type[] { typeof(Person) };        }    }}

然后在反序列化之前,我們把這個轉換注冊到實體對象中,這時再執行,程序就一切正常了:

JavaScriptSerializer serializer = new JavaScriptSerializer();serializer.RegisterConverters(new JavaScriptConverter[] { new PersonJsConverter(),  });var deserialize = serializer.Deserialize<Person>(noChildStr);

2、在使用Json.net時,采用了一種更加優雅的方式來處理這個問題--JsonConverter,它可以單獨處理一個指定的類成員變量。這樣就不用像上面的JavaScriptConverter一樣處理整個類的所有成員。代碼如下:

public class GuidConverter : JsonConverter{    public override bool CanConvert(Type objectType)    {        return objectType.IsAssignableFrom(typeof(Guid));    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        try        {            return Guid.Parse(reader.Value.ToString());         }        catch        {            //如果傳進來的值造成異常,則賦值一個初值            return Guid.Empty;        }    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        serializer.Serialize(writer, value);    }}

值得注意的是JsonConverter是一個Attribute,所以要在類成員上面添加一個特性:

  public class Person    {        public string Name;        public int Age;        [JsonConverter(typeof(GuidConverter))]        public Guid TokenId { get; set; }        public DateTime RegTime;        public Person Child;        public Person Friend;    }

這時,再運行程序時,TokenId就會被賦上一個初始的值??磥碓诜葱蛄谢?,Json.net還是更勝一籌。

性能

這是網上給出來兩個的性能比較:

綜上,在不考慮系統對第三方控件引用的要求情況下,盡量使用Json.net來進行對象序列化處理。

 

其他常用的序列化方法

說了半天,回顧一下序列化的定義:

序列化:將對象轉換成字節流的過程,這樣就可以輕松將對象保存在磁盤文件或數據庫中。

反序列化:序列化的逆過程,就是將字節流轉換回原來的對象的過程。

其他各種格式序列化的方法請參考:

序列化與反序列化,及Json序列化反序列化

談談:.Net中的序列化和反序列化


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
4438全国亚洲精品在线观看视频| 国产精品女主播| 欧美成人国产va精品日本一级| 亚洲女人天堂色在线7777| 精品久久香蕉国产线看观看gif| 欧美一区亚洲一区| 亚洲一区二区久久| 国产精品美女久久久免费| 日本高清视频一区| 亚洲自拍偷拍色片视频| 在线一区二区日韩| 欧美极品少妇xxxxx| 日韩高清有码在线| 91亚洲va在线va天堂va国| 77777少妇光屁股久久一区| 欧美小视频在线| 亚洲第一免费播放区| 欧美日韩国产精品一区二区三区四区| 亚洲伦理中文字幕| 国产精品18久久久久久麻辣| 久久影院在线观看| 911国产网站尤物在线观看| 欧美成人性色生活仑片| 久久中文久久字幕| 国产做受高潮69| 日韩在线播放一区| 宅男66日本亚洲欧美视频| 97视频com| 久久久久久久久久久网站| 亚洲精品av在线播放| 亚洲欧洲免费视频| 91精品久久久久久久| 91中文字幕一区| 91在线观看免费网站| 欧美日韩激情小视频| 国产91成人在在线播放| 岛国精品视频在线播放| 成人激情视频在线播放| 久久99久久久久久久噜噜| 最近2019年中文视频免费在线观看| 国产一区在线播放| 国产精品白丝jk喷水视频一区| 欧美诱惑福利视频| 日韩免费观看网站| 欧美色videos| 91久久国产精品91久久性色| 中文字幕av一区二区三区谷原希美| 欧美人成在线视频| 欧美日韩免费看| 国产成人精品一区二区在线| 亚洲级视频在线观看免费1级| 欧美日韩在线视频一区二区| 午夜免费在线观看精品视频| 欧美国产精品日韩| 国产精品自拍视频| 国产精品永久免费视频| 亚洲女人天堂视频| 欧美色播在线播放| 国产成人久久久精品一区| 中文字幕久久亚洲| 日韩福利在线播放| 久久精品视频va| 91精品视频免费| 亚洲免费高清视频| 久久久久久国产精品美女| 中文字幕亚洲欧美在线| 国产精品白嫩初高中害羞小美女| 国产精品流白浆视频| 伊人久久久久久久久久久| 亚洲一区制服诱惑| 久久99久久久久久久噜噜| 国产精品va在线播放我和闺蜜| y97精品国产97久久久久久| 亚洲国产成人久久综合一区| 2021久久精品国产99国产精品| 亚洲国产小视频| 欧美日韩国产成人在线观看| 亚洲国产精品成人av| 最新的欧美黄色| 91av中文字幕| 国产欧美精品日韩| 不卡av日日日| 国产成人自拍视频在线观看| 精品国产一区二区三区四区在线观看| 久久久国产精品x99av| 操日韩av在线电影| 中文国产成人精品| 不卡av在线网站| 欧美乱人伦中文字幕在线| 91国语精品自产拍在线观看性色| 欧美日韩国产麻豆| 欧美一级成年大片在线观看| 久久久久成人精品| 国自产精品手机在线观看视频| 91免费高清视频| 97久久伊人激情网| 色天天综合狠狠色| 亚洲第一页自拍| 日韩精品视频在线免费观看| 亚洲第一精品夜夜躁人人爽| 国产日韩在线一区| 日韩av片永久免费网站| 最好看的2019年中文视频| 超碰精品一区二区三区乱码| 亚洲美女免费精品视频在线观看| 亚洲精品动漫久久久久| 亚洲精品国产精品国自产在线| 欧美精品成人91久久久久久久| 国产精品香蕉国产| wwwwwwww亚洲| 91精品国产乱码久久久久久久久| 成年人精品视频| 亚洲午夜久久久久久久| 色伦专区97中文字幕| 日本精品久久久| 91影视免费在线观看| 国产精品黄色av| 久久久久九九九九| 日韩精品一区二区视频| 日本免费久久高清视频| 69久久夜色精品国产69| 欧美不卡视频一区发布| 欧美日韩性生活视频| 不卡伊人av在线播放| 精品一区二区三区电影| 亚洲xxx大片| 欧美激情2020午夜免费观看| 精品亚洲一区二区三区| 欧美视频不卡中文| 一本色道久久综合狠狠躁篇怎么玩| 国产狼人综合免费视频| 国产精品久久久久久久一区探花| 日韩激情在线视频| 26uuu久久噜噜噜噜| 日韩电影免费观看在线| 精品国产乱码久久久久久天美| 欧美性视频精品| 日本久久亚洲电影| 亚洲国产成人久久综合| 成人午夜在线影院| 国产亚洲欧美日韩精品| 亚洲精品国偷自产在线99热| 日韩电影第一页| 国语自产偷拍精品视频偷| 久久久久久国产精品久久| 欧美精品精品精品精品免费| 久久久精品免费| 亚洲国产精品悠悠久久琪琪| 国产精品极品美女粉嫩高清在线| 成人激情视频在线观看| 亚洲理论在线a中文字幕| 国产精品成人久久久久| 97香蕉超级碰碰久久免费的优势| 欧美一级大片在线观看| 日韩av在线网址| 欧美精品激情blacked18| 国产精品国产三级国产专播精品人| 国产欧美精品一区二区三区介绍| 亚洲一区中文字幕| 亚洲精品美女网站| 91日本视频在线| 欧美大尺度电影在线观看| 欧美性猛交xxxx黑人猛交| 精品福利在线看|