日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

System.Text.Json 自定义 Conveter

發(fā)布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 System.Text.Json 自定义 Conveter 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

System.Text.Json 自定義 Conveter

Intro

System.Text.Json 作為現(xiàn)在 .NET 默認提供的高性能 JSON 序列化器,對于一些比較特殊類型支持的并不太好,業(yè)務需求中總是有各種各樣的需要,很多時候就需要用到自定義 Converter ,對于微軟新出的 DateOnly/TimeOnly 也是需要自定義 Converter 來支持的

Sample

遇到一個(偽)需求,一個 Id 屬性可能是字符串也可能是整型數(shù)字,舉個栗子,

{"Id":?1,?"Name":?"Test"}{"Id":?"這是一個?Id",?"Name":?"Test"}

上面這是兩個 JSON,想實現(xiàn)用同一個 Model 來保存結(jié)果,應該怎么做呢?

如果 Id 只會是整數(shù)或者整數(shù)的字符串,那么我們就可以用 int 來表示,System.Text.Json 從 5.0 開始支持解析帶引號的數(shù)字,也就是數(shù)字的字符串形式可以參考:https://github.com/dotnet/runtime/issues/30255,只需要配置 JsonNumberHandling, 在 ASP.NET Core 中默認是啟用的,是可以把 "1" 反序列化成一個 int 類型的

但是我們的示例中的 Id 是可能不是數(shù)字的,轉(zhuǎn)成數(shù)字可能會失敗的,所以想要把它當作 string 來處理,最后 model 是這樣的

public?record?TestModel {public?string?Id?{?get;?init;?}?=?default!;public?string??Name?{?get;?set;?} }

但是如果是上面第一種形式的 JSON 反序列化時會發(fā)生錯誤,異常如下:

所以還需要自定義一個 Converter 來支持將數(shù)字轉(zhuǎn)換成一個字符串,Converter 實現(xiàn)如下,? 屬性類型是什么,泛型類型就應該是什么

public?class?StringOrIntConverter?:?JsonConverter<string> {public?override?string?Read(ref?Utf8JsonReader?reader,?Type?typeToConvert,?JsonSerializerOptions?options){if?(reader.TokenType?==?JsonTokenType.Number){return?reader.GetInt32().ToString();}return?reader.GetString();}public?override?void?Write(Utf8JsonWriter?writer,?string?value,?JsonSerializerOptions?options){writer.WriteStringValue(value);} }

使用 Converter 的方式有兩種,一種是在某個屬性上添加 JsonConverter 來使用,另一種是作為全局 Converter 來使用,直接配置 JsonSerializerOptions 中的 Converter

屬性使用 Converter 示例:

public?record?TestModel {[JsonConverter(typeof(StringOrIntConverter))]public?string?Id?{?get;?init;?}?=?default!;public?string??Name?{?get;?set;?} }

配置 JsonSerializerOptions示例:

JsonSerializer.Deserialize<TestModel>(node.ToJsonString(),?new?JsonSerializerOptions{Converters?={new?StringOrIntConverter()}});

這樣我們就可以支持從一個 int 到 string 的轉(zhuǎn)換了,完整示例如下:

var?model?=?new?TestModel {Id?=?"123",Name?=?"456" }; var?jsonString?=?JsonSerializer.Serialize(model); WriteLine(jsonString); var?node?=?JsonNode.Parse(jsonString); ArgumentNullException.ThrowIfNull(node,?nameof(node)); node["Id"]?=?123; var?newJsonString?=?node.ToJsonString(); WriteLine(newJsonString); var?newModel?=?JsonSerializer.Deserialize<TestModel>(newJsonString); WriteLine(model?==?newModel);node["Name"]?=?345; WriteLine(JsonSerializer.Deserialize<TestModel>(node.ToJsonString(),?new?JsonSerializerOptions {Converters?={new?StringOrIntConverter()} })?.Name);

輸出結(jié)果如下:

output

More

可能你會問為什么不直接用 object,如果使用 object 的話,上面的 Equals 判斷就要改寫了,需要自己重新實現(xiàn)比較邏輯,而用 string 就不需要了 希望上面自定義 Converter 的代碼對你有所幫助~

References

  • https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?WT.mc_id=DT-MVP-5004222

  • https://github.com/dotnet/runtime/issues/30255

  • https://github.com/dotnet/runtime/pull/39685

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/JsonSample/SystemTextJsonSample/CustomConvertSample.cs

總結(jié)

以上是生活随笔為你收集整理的System.Text.Json 自定义 Conveter的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。