使用 C# 9 的records作为强类型ID - JSON序列化
发布日期:2021-05-09 05:28:40 浏览次数:17 分类:博客文章

本文共 7409 字,大约阅读时间需要 24 分钟。

������������������������������������������������������������ID������������������������ JSON ������������������������������������

{    "id": {        "value": 1    },    "name": "Apple",    "unitPrice": 0.8}

������������������������������������������������������������������������ID���record������������������������������������������������������������������������������������������������������������������������������������������������������������������������

System.Text.Json

������������������ASP.NET Core������3.0������������������JSON������������������System.Text.Json������������������������������������

���������������������id��������������������������������������������������������������������� JsonConverter���

public class StronglyTypedIdJsonConverter
: JsonConverter
where TStronglyTypedId : StronglyTypedId
where TValue : notnull{ public override TStronglyTypedId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType is JsonTokenType.Null) return null; var value = JsonSerializer.Deserialize
(ref reader, options); var factory = StronglyTypedIdHelper.GetFactory
(typeToConvert); return (TStronglyTypedId)factory(value); } public override void Write(Utf8JsonWriter writer, TStronglyTypedId value, JsonSerializerOptions options) { if (value is null) writer.WriteNullValue(); else JsonSerializer.Serialize(writer, value.Value, options); }}

������������������������������������ id.value, ������������������������������������������id���������������������������������

���������������������������:

services.AddControllers()    .AddJsonOptions(options =>    {        options.JsonSerializerOptions.Converters.Add(            new StronglyTypedIdJsonConverter
()); });

���������������������������������

{    "id": 1,    "name": "Apple",    "unitPrice": 0.8}

���������������������������������������������������������������������������ProductId������������������������������������������������������ID���������������������������������������������������������������������id������������������������������������������������������������(ConverterFactory),���������������������

public class StronglyTypedIdJsonConverterFactory : JsonConverterFactory{    private static readonly ConcurrentDictionary
Cache = new(); public override bool CanConvert(Type typeToConvert) { return StronglyTypedIdHelper.IsStronglyTypedId(typeToConvert); } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { return Cache.GetOrAdd(typeToConvert, CreateConverter); } private static JsonConverter CreateConverter(Type typeToConvert) { if (!StronglyTypedIdHelper.IsStronglyTypedId(typeToConvert, out var valueType)) throw new InvalidOperationException($"Cannot create converter for '{typeToConvert}'"); var type = typeof(StronglyTypedIdJsonConverter<,>).MakeGenericType(typeToConvert, valueType); return (JsonConverter)Activator.CreateInstance(type); }}

���������������������������������������������������������������������������������id������������������������������������������������������������������������������������������������������������������������

������������������������������������JsonConvert������������������������Factory���������������������������������������������������������������������������������������ID

services.AddControllers()    .AddJsonOptions(options =>    {        options.JsonSerializerOptions.Converters.Add(            new StronglyTypedIdJsonConverterFactory());    });

Newtonsoft.Json

������������������������������Newtonsoft.Json������JSON���������������������������������

������������������������������Newtonsoft.Json ������������compatible JsonConverter������������������������������������TypeConverter, ������TypeConverter������������������������������������string���������������������������������������, ��������������������������� TypeConverter���Newtonsoft.Json���������������������������������������

{    "id": "1",    "name": "Apple",    "unitPrice": 0.8}

������������������������������id������������������������������������������������������������������id������GUID���������������������int������������������������������������������������������������

������ System.Text.Json ���������������������������������������������Newtonsoft.Json������������������������ConvertFactory������������������������������������������������������������������

public class StronglyTypedIdNewtonsoftJsonConverter : JsonConverter{    private static readonly ConcurrentDictionary
Cache = new(); public override bool CanConvert(Type objectType) { return StronglyTypedIdHelper.IsStronglyTypedId(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var converter = GetConverter(objectType); return converter.ReadJson(reader, objectType, existingValue, serializer); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is null) { writer.WriteNull(); } else { var converter = GetConverter(value.GetType()); converter.WriteJson(writer, value, serializer); } } private static JsonConverter GetConverter(Type objectType) { return Cache.GetOrAdd(objectType, CreateConverter); } private static JsonConverter CreateConverter(Type objectType) { if (!StronglyTypedIdHelper.IsStronglyTypedId(objectType, out var valueType)) throw new InvalidOperationException($"Cannot create converter for '{objectType}'"); var type = typeof(StronglyTypedIdNewtonsoftJsonConverter<,>).MakeGenericType(objectType, valueType); return (JsonConverter)Activator.CreateInstance(type); }}public class StronglyTypedIdNewtonsoftJsonConverter
: JsonConverter
where TStronglyTypedId : StronglyTypedId
where TValue : notnull{ public override TStronglyTypedId ReadJson(JsonReader reader, Type objectType, TStronglyTypedId existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType is JsonToken.Null) return null; var value = serializer.Deserialize
(reader); var factory = StronglyTypedIdHelper.GetFactory
(objectType); return (TStronglyTypedId)factory(value); } public override void WriteJson(JsonWriter writer, TStronglyTypedId value, JsonSerializer serializer) { if (value is null) writer.WriteNull(); else writer.WriteValue(value.Value); }}

���������������������������������������

services.AddControllers()        .AddNewtonsoftJson(options =>        {            options.SerializerSettings.Converters.Add(                new StronglyTypedIdNewtonsoftJsonConverter());        });

���������������������������������������������������������������������

{    "id": 1,    "name": "Apple",    "unitPrice": 0.8}

������������: thomas levesque

���������������

������

������������������������������������ ���������������������������������������������������������������������������������������������������QQ��� 897216102

上一篇:使用 gRPCurl 调试.NET 5的gPRC服务
下一篇:使用 C# 9 的records作为强类型ID - 路由和查询参数

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月09日 16时23分13秒