C#中System.Text.Json匿名對象反序列化
以前就是一直使用 Newtonsoft.Json
用起來還是挺舒服的。由于 JSON 的應(yīng)用越來越廣,現(xiàn)在. NET Core 都內(nèi)置了 System.Text.Json
可以直接對 JSON 進(jìn)行操作,不過兩個東西的體驗(yàn)依然有點(diǎn)區(qū)別。
有時(shí)候我們會遇到的從第三方傳遞過來的 json string 對象,對其進(jìn)行解析并不需要所有的字段,只需要一個目標(biāo)的字段時(shí),可以考慮使用匿名對象/動態(tài)對象對其反序列化。
之前的
Newtonsoft.Json
好像直接使用 dynamic,運(yùn)用 JObject 進(jìn)行處理,現(xiàn)在的不是那么容易。下文代碼基于. NET 6,為了代碼整潔,實(shí)際配置了 PropertyNameCaseInsensitive = true,但是下面代碼中并沒有體現(xiàn)。
數(shù)據(jù)
我們定義了如下的類型,并從 OData 獲得了 str
字符串型數(shù)據(jù)。
public readonly static string str = """ {"@odata.context":"http://localhost:9000/api/v1/$metadata#DataDto","value":[{"id":"0b734ed7-2955-4af4-a902-35dc17871094","timestamp":1684839865920},{"id":"7e285d08-cdb3-4209-8335-0ff9b20d39ef","timestamp":1684836312421}]} """; public class DataDto { public string? Id { get; set; } public long Timestamp { get; set; } }
由于有元數(shù)據(jù),我們無法直接將上面的字符串反序列化為 DataDto 的列表對象。
自定義類
最簡單的方式,是對應(yīng)此類對象,設(shè)計(jì)一個只用于反序列化的新類。
public class ODataEnumerableResultWrapper<T> where T : class { public IEnumerable<T> Value { get; set; } } var meta = JsonSerializer.Deserialize<ODataEnumerableResultWrapper<DataDto>>(str); var target = meta.Value;
匿名方式
可以使用 JsonNode 來直接反序列化,并使用類似鍵值對的形式訪問。
public static void Main() { JsonNode? meta = JsonSerializer.Deserialize<JsonNode>(str); //如果直接是簡單的對象,而不是數(shù)組,可以使用GetValue<T>這種形式。 var count = meta?["value"]?.Deserialize<IEnumerable<DataDto>>().Count(); Console.WriteLine(count); } }
注意,這樣的操作和你反序列化為 JsonDocument/JsonElement 并沒有什么本質(zhì)的區(qū)別。
動態(tài)方式
由于設(shè)計(jì)區(qū)別,直接使用 dynamic 進(jìn)行反序列化,得到的對象并不具有一般 dynamic 的性質(zhì)(實(shí)際上是 System.Text.Json.JsonElement
對象)。因此,我們無法通過的 dynamic 訪問成員的形式進(jìn)行操作。
dynamic meta = JsonSerializer.Deserialize<dynamic>(str); Console.WriteLine(meta.GetType()); //OUTPUT: System.Text.Json.JsonElement
有 文章 說可以使用 ExpandoOject 實(shí)現(xiàn),但是實(shí)際上無法對子級對象進(jìn)行類似的訪問,因?yàn)楂@取的子級對象,實(shí)際上是 JsonElement
。
dynamic meta = JsonSerializer.Deserialize<System.Dynamic.ExpandoObject>(str); Console.WriteLine(meta.GetType()); //System.Dynamic.ExpandoObject Console.WriteLine(meta.value); //[{"id":"0b734ed7-2955-4af4-a902-35dc17871094","timestamp":1684839865920},{"id":"7e285d08-cdb3-4209-8335-0ff9b20d39ef","timestamp":1684836312421}] Console.WriteLine(meta.value.GetType()); //System.Text.Json.JsonElement
當(dāng)然可以通過自定義序列化的方式操作(見參考),但是這個辦法與我們的不寫額外代碼的初衷相沖突,因此不考慮了。
參考
到此這篇關(guān)于System.Text.Json匿名對象反序列化的文章就介紹到這了,更多相關(guān)System.Text.Json反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用AutoMapper進(jìn)行對象映射的示例代碼
AutoMapper 是一個對象到對象映射的庫,可以簡化 DTO (Data Transfer Objects) 和實(shí)體類之間的轉(zhuǎn)換,在大型應(yīng)用程序中,通常需要將業(yè)務(wù)實(shí)體映射到視圖模型或 DTO 中,本文將詳細(xì)介紹如何在 C# 項(xiàng)目中使用 AutoMapper,包括安裝、配置、以及示例代碼2024-08-08C#實(shí)現(xiàn)多種圖片格式轉(zhuǎn)換的示例詳解
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)多種圖片格式轉(zhuǎn)換,例如轉(zhuǎn)換成圖標(biāo)圖像ICO,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01C#把數(shù)組中的某個元素取出來放到第一個位置的實(shí)現(xiàn)方法
這篇文章主要介紹了C#把數(shù)組中的某個元素取出來放到第一個位置的實(shí)現(xiàn)方法,涉及C#針對數(shù)組的常見操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-12-12unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解
這篇文章主要介紹了unity中實(shí)現(xiàn)Edge瀏覽器鼠標(biāo)手勢的功能思路詳解,實(shí)現(xiàn)起來其實(shí)并不復(fù)雜,涉及的技術(shù)點(diǎn)有pc端和移動端屏幕拖動事件,二維向量的相關(guān)運(yùn)算,手勢匹配算法,事件系統(tǒng)設(shè)計(jì)模式,需要的朋友可以參考下2023-12-12