C#中System.Text.Json匿名對象反序列化
以前就是一直使用 Newtonsoft.Json 用起來還是挺舒服的。由于 JSON 的應(yīng)用越來越廣,現(xiàn)在. NET Core 都內(nèi)置了 System.Text.Json 可以直接對 JSON 進行操作,不過兩個東西的體驗依然有點區(qū)別。
有時候我們會遇到的從第三方傳遞過來的 json string 對象,對其進行解析并不需要所有的字段,只需要一個目標(biāo)的字段時,可以考慮使用匿名對象/動態(tài)對象對其反序列化。
之前的
Newtonsoft.Json好像直接使用 dynamic,運用 JObject 進行處理,現(xiàn)在的不是那么容易。下文代碼基于. NET 6,為了代碼整潔,實際配置了 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è)計一個只用于反序列化的新類。
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è)計區(qū)別,直接使用 dynamic 進行反序列化,得到的對象并不具有一般 dynamic 的性質(zhì)(實際上是 System.Text.Json.JsonElement 對象)。因此,我們無法通過的 dynamic 訪問成員的形式進行操作。
dynamic meta = JsonSerializer.Deserialize<dynamic>(str); Console.WriteLine(meta.GetType()); //OUTPUT: System.Text.Json.JsonElement
有 文章 說可以使用 ExpandoOject 實現(xiàn),但是實際上無法對子級對象進行類似的訪問,因為獲取的子級對象,實際上是 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#實現(xiàn)服務(wù)器性能監(jiān)控并發(fā)送郵件保存日志
這篇文章主要介紹了c#實現(xiàn)服務(wù)器性能監(jiān)控并發(fā)送郵件保存日志的示例,代碼分為客戶端和服務(wù)端,客戶端可安裝為本地服務(wù)形式啟動2014-01-01
基于C#實現(xiàn)12306的動態(tài)驗證碼變成靜態(tài)驗證碼的方法
這篇文章主要介紹了基于C#實現(xiàn)12306的動態(tài)驗證碼變成靜態(tài)驗證碼的方法的相關(guān)資料,需要的朋友可以參考下2015-12-12
C#函數(shù)式編程中的遞歸調(diào)用之尾遞歸詳解
這篇文章主要介紹了C#函數(shù)式編程中的遞歸調(diào)用詳解,本文講解了什么是尾遞歸、尾遞歸的多種方式、尾遞歸的代碼實例等內(nèi)容,需要的朋友可以參考下2015-01-01

