Newtonsoft—Json.NET常用方法簡述

来源:https://www.cnblogs.com/512kd/archive/2019/11/01/11774756.html
-Advertisement-
Play Games

Json.NET常用方法彙總(可解決日常百分之90的需求) 0.Json.NET基礎用法 首先去官網下載最新的Newtonsoft.Json.dll(也可以使用VS自帶的NuGet搜索Json.NET下載(下載下圖第二個))並引用至項目。 (1)序列化實體類(將實體類對象序列化為Json字元串) 結 ...




 

Json.NET常用方法彙總(可解決日常百分之90的需求)

 

0.Json.NET基礎用法


   首先去官網下載最新的Newtonsoft.Json.dll(也可以使用VS自帶的NuGet搜索Json.NET下載(下載下圖第二個))並引用至項目。

  

  • (1)序列化實體類(將實體類對象序列化為Json字元串)
using System;
using Newtonsoft.Json;

namespace Json_NET_Test
{
    /// <summary>
    /// 定義一個實體類
    /// </summary>
    public class Student
    {
        public string Name;
        public int Age;
        public string Class;
    }
    class Program
    {
        static void Main(string[] args)
        {
            //創建實體類對象           
            Student stu = new Student
            {
                Name = "老王",
                Age = 99,
                Class = "三班"
            };
            //開始序列化
            string jsonStr = JsonConvert.SerializeObject(stu, Formatting.Indented);
            Console.WriteLine(jsonStr);
        }
    }
}

  結果:

  

  • (2)反序列化(將Json字元串反序列化為實體類對象)
using System;
using Newtonsoft.Json;

namespace Json_NET_Test
{
    /// <summary>
    /// 定義一個實體類
    /// </summary>
    public class Student
    {
        public string Name;
        public int Age;
        public string Class;
    }
    class Program
    {
        static void Main(string[] args)
        {
            //Json字元串
            string jsonStr = "{\"Name\": \"老王\",\"Age\": 99,\"Class\": \"三班\"}";
            //開始反序列化
            Student stu = JsonConvert.DeserializeObject<Student>(jsonStr);
        }
    }
}

 

1.序列化與反序列化時忽略某些屬性


  •  (1)忽略類內所有屬性

  [JsonObject(MemberSerialization.OptIn)]用於在序列化與反序列化時忽略一個類里所有的屬性,只有當在類內屬性上打特性標簽[JsonProperty]時才支持序列化與反序列化。所以[JsonObject(MemberSerialization.OptIn)]常用於與[JsonProperty]配合使用。

  例:

[JsonObject(MemberSerialization.OptIn)]
public class Person
{
    public int Age { get; set; }

    [JsonProperty]
    public string Name { get; set; }

    public string Sex { get; set; }

    public bool IsMarry { get; set; }

    public DateTime Birthday { get; set; }
}

 

  • (2)序列化所有屬性(預設)

  預設實體類上預設打著[JsonObject(MemberSerialization.OptOut)]特性標簽(可以省略不寫),如果要忽略某些屬性,要在屬性上打[JsonIgnore]。

  例:

[JsonObject(MemberSerialization.OptOut)]
public class Person
{
    public int Age { get; set; }

    public string Name { get; set; }

    public string Sex { get; set; }

    [JsonIgnore]
    public bool IsMarry { get; set; }

    public DateTime Birthday { get; set; }
}

 

  • (3)動態控制實體類屬性的是否忽略序列化(預設)

  當某些條件下需要序列化A屬性和B屬性,某些情況下需要忽略A屬性與B屬性,我們該怎麼做?
  答:使用JsonSerializerSettings設置某實體類對象要忽略序列化的屬性(配合if與else控制屬性的動態忽略)。

  例:以下方式忽略p對象的Age屬性與IsMarry屬性:

  JsonSerializerSettings jsetting=new JsonSerializerSettings();
  jsetting.ContractResolver = new LimitPropsContractResolver(new string[] { "Age", "IsMarry" });
  Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

 

2.預設值處理


  •  (1)設置屬性預設值

  在屬性上打 [DefaultValue("xxx")]

 

3.空值處理


  •  (1)不序列化為null的屬性(使用JsonSerializerSettings方式)
    Person p = new Person 
    { 
         room = null,
         Age = 10, 
         Name = "張三豐", 
         Sex = "", 
         IsMarry = false, 
         Birthday = new DateTime(1991, 1, 2) 
    };
    JsonSerializerSettings jsetting=new JsonSerializerSettings();
    jsetting.NullValueHandling = NullValueHandling.Ignore;
    Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

  ps:使用這種方式可能bool為false的也無法序列,最後的結果只包含Birthday、Sex、Name、Age。

 

  • (2)不序列化為null的屬性(使用特性標簽方式)
[JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
public Room room { get; set; }

 

4.序列化私有成員


   因為預設只序列化public的成員,所以如果想序列化private成員,要在實體類的屬性上打[JsonProperty]標簽。

[JsonProperty]
private int Height { get; set; }

 

5.自定義序列化名稱


   在序列化與反序列化時可以自定義序列化出字元串的屬性名稱,如下代碼可以將實體類的Name屬性序列化為CName屬性,並且可以將Json中的CName反序列化為當前實體類的Name屬性。(雙向)

[JsonProperty(PropertyName = "CName")]
public string Name { get; set; }

 

6.日期處理


  • (1)解決方案1:在可以動Model代碼的情況下

  系統自帶的DateTime會格式化成iso日期標準,但是實際使用過程中大多數使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss兩種格式的日期,解決辦法是可以將DateTime類型改成string類型自己格式化好,然後在序列化。
  例:

    [JsonProperty(PropertyName = "startTime")]//因為預設只序列化public屬性,所以要打上JsonProperty標簽並且聲明名稱
    private string m_StartTime{get;set;}

    [JsonIgnore]//這個標簽用於在序列化與反序列化時忽略StartTime屬性
    public DateTime StartTime
    {
        get{ return Convert.ToDateTime(m_StartTime); }
        set
        {
            DateTime time = value;
            m_StartTime = time.ToString("yyyy-MM-dd");//這裡寫自己想要的格式
        }
    }

  ps:代碼思路是不去序列化StartTime屬性,而去序列化string類型的m_StartTime屬性(m_StartTime相當於StartTime屬性的私有欄位)。

 

  • (2)解決方案2:使用DateTimeConverterBase

  Json.Net提供了IsoDateTimeConverter日期轉換這個類,可以通過JsnConverter實現相應的日期轉換

[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime Birthday { get; set; }

  但是IsoDateTimeConverter日期格式(yyyy-MM-ddTHH:mm:ss)不是我們想要的,我們可以繼承該類實現自己的日期
  例:

    public class ChinaDateTimeConverter : DateTimeConverterBase
    {
        private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            dtConverter.WriteJson(writer, value, serializer);
        }
    }

  使用方式:

[JsonConverter(typeof(ChinaDateTimeConverter))]
public DateTime Birthday { get; set; }

 

7.以駝峰命名法序列化


   有時我們會碰到這種需求,比如我們代碼里實體類型的屬性名稱均是以大寫字母開頭,如Name、StartTime等,但是要求我們序列出的Json字元串的屬性名稱要以小寫字母開頭,如name、startTime、endTime等。我們可以使用如下代碼解決

JsonSerializerSettings setting = new JsonSerializerSettings();
setting.ContracResolver = new CamelCasePropertyNamesContractResolver();
string jsonStr = JsonConvert.Serializeobject(p, Newtonsoft.json.Formatting.Indented, setting);

  這樣子的話,在序列實體類對象p的屬性時,屬性名稱將由PersonName轉換為personName。

 

8.枚舉的序列化


   枚舉預設序列化為枚舉的Int值,如果想要序列化為枚舉string值,使用如下方式

  [JsonConverter(typeof(StringEnumConverter))]   public NotifyTypeEnum Type { get; set; }

 

9.將多個數據類型序列化為1個Json對象(序列化匿名類)


   有時我們有這樣的需求,對方要求我們傳輸過去的Json字元串要包含我們多個實體類型的信息,笨方法就是重新構建一個符合要求的實體類型,但是我們又更好的方法,我們可以使用匿名類,把Json需要的信息均放在匿名類中,我們可以對匿名類進行序列化。

  例:

        List<Model> list1 = new List<Model>();
        List<Model2> list2 = new List<Model2>();
        string name = "名字";
        string address = "xx";
        List<string> info = new List<string>() { name, address };
        var json = new { information = info, jsonList1 = list1, jsonList2 = list2 }; 

  我們只需要對上面的匿名對象“json”序列化即可。

 

10.使用JsonConverter自定義屬性序列化規則(json格式轉換器)


  •  (1)將屬性值由double類型序列化時轉為字元串類型
  public class DoubleToStringConverter : JsonConverter
    {
        //表示反序列化時不執行該轉換器
        public override bool CanRead => false;
        //表示序列化時執行該轉換器
        public override bool CanWrite => true;

        //判斷執行條件(當屬性的值為double類型時才使用轉換器)
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(double);
        }

        //因為public override bool CanRead => false;,所以不用實現反序列化時的轉換方法
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 序列化時執行的轉換
        /// </summary>
        /// <param name="writer">可以用來重寫值</param>
        /// <param name="value">屬性的原值</param>
        /// <param name="serializer">就是那個serializer對象</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            double v = (double)value;
            writer.WriteValue(v.ToString());
        }
    }

  使用方式:

[JsonConverter(typeof(DoubleToStringConverter))]
public double Count{get;set;}

  ps:這樣子,就可以把原本序列化出的Json字元串   Count : 12.3   轉化為   Count : "12.3"
  ps:[JsonConverter(typeof(DoubleToStringConverter))]也可以打在類上,表示全局設置

 

  • (2)枚舉轉換為int字元串

  為什麼要進行這樣的轉換呢?

  因為枚舉類型在序列化時預設序列化為枚舉的int類型,即如下代碼:

   /// <summary>
    /// 自定義一個枚舉類型
    /// </summary>
    public enum MyEnum
    {
        aaa = 1,
        bbb = 2,
        ccc = 3
    }
    /// <summary>
    /// 實體類(類內有一個枚舉類型的屬性MyEnumProp)
    /// </summary>
    public class Person
    {
        public MyEnum MyEnumProp { get; set; }
    }
    class Program
    {

        static void Main(string[] args)
        {
            Person p = new Person() { MyEnumProp = MyEnum.ccc };
            //Json字元串
            string jsonStr = JsonConvert.SerializeObject(p);
            //開始反序列化
            Console.WriteLine(jsonStr);
            Console.ReadLine();
        }
    }

  結果為:

  

   有時候會有這樣的需求,序列化出的屬性值均要為字元串格式,即要將上圖結果的3改為"3"。這時候就需要自定義轉換了!

  代碼如下:

    public class EnumToIntStringConverter : JsonConverter
    {
        //反序列化時不執行
        public override bool CanRead => false;
        //序列化時執行
        public override bool CanWrite => true;

        //控制執行條件(當屬性的值為枚舉類型時才使用轉換器)
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Enum);
        }

        //因為public override bool CanRead => false;,所以不用實現反序列化時的轉換方法
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 序列化時執行的轉換
        /// </summary>
        /// <param name="writer">可以用來重寫值</param>
        /// <param name="value">屬性的原值</param>
        /// <param name="serializer">就是那個serializer對象</param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Enum e = (Enum)value;
            int v = Convert.ToInt32(e);
            writer.WriteValue(v.ToString());
        }
    }  

  使用方法同上例。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在對網站信息進去抓取時,難免遇到被封IP的情況。針對這一情況可採用代理IP的方法來處理,好了 現在我遇到的問題是什麼呢? 就是我沒有代理IP啊。 百度了下,發現網上有好多免費的代理IP,所以我決定把能找到的所以免費代理IP全部採集下來,以後做成介面的方式來供大家免費使用。 本篇文章主要是對採集 “6 ...
  • python day 19 2019/10/31 [TOC] 學習資料來自老男孩教育 1. 購物商城作業要求 2. 多進程 2.1 簡述多進程 程式 :是一個指令的集合 進程 :正在執行的程式;或者說,當你運行一個程式,你就啟動了一個進程。 1. 編寫完的代碼,沒有運行時,稱為程式;正在運行的代碼, ...
  • 設計模式的六大原則 單一職責原則 里氏替換原則 依賴倒置原則 介面隔離原則 迪米特原則 開閉原則 設計模式的分類 創建型模式 創建型模式:對對象實例化的抽象,通過採用抽象類所定義的介面,封裝了系統中對象如何創建,組合等信息。包括以下幾種設計模式 抽象工廠模式 優點 分離了具體類 更容易在產品系列中進 ...
  • 聽很多Python大神聊過,Python非常適合初學者入門。因為,相比較其他不少主流編程語言,Python有更好的可讀性,上手相對容易。它自帶的各種模塊加上豐富的第三方模塊,免去了很多“重覆造輪子”的工作,可以更快地寫出東西。配置開發環境也不是很複雜,Mac和Linux都內置了Python。 廢話不 ...
  • ▶ Spring Boot 依賴與配置 Maven 依賴 ▶ 使用說明 假設有配置項 不能明文顯示,則可以使用 的 演算法加密演算法進行如下配置: 為自定義值,用此密碼加密的明文,需要用此密碼解密密文 為 提供的加密標識,Spring Boot 服務啟動時,載入各種 properties 時會依據此標識 ...
  • 前言 先談談“異常處理”這件事。下麵有 2 份偽代碼,對比下: 可以看出,如果使用異常替代返回錯誤碼,錯誤處理代碼就能從主路徑邏輯中分離出來,得到簡化! ②中,基於異常處理的代碼真的好嗎?其實是醜陋不堪的,它搞亂了代碼結構,把錯誤處理與正常流程混為一談。最好把 try 和 catch 代碼塊的主體部 ...
  • 設計模式可以使用我們在軟體開發過程中更加靈活,軟體的擴展更容易,軟體的耦合度更低,設計模式不是在開發中刻意去用的,而是到了什麼時候用什麼模式的,不能強迫的使用它,應該是自然而然的想到它。 單例模式 在23種設計模式中,單例最為簡單和純粹,也是最容易理解的,即它在軟體生命周期里,只有一個實例,就是說你 ...
  • 這兩個主題沒什麼關係,但是怕文章太短被移除主頁。 using聲明 using語句塊 這兩個主題沒什麼關係,但是怕文章太短被移除主頁。 using聲明 using語句塊 儘管.NET Core運行時有垃圾收集器(GC)來負責記憶體清理工作,但是我們還是要自己確保當非托管資源不再使用的時候應該被清理掉。以 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...