如何在反序列化之前使用 System.Text.Json 验证 JSON
Posted
技术标签:
【中文标题】如何在反序列化之前使用 System.Text.Json 验证 JSON【英文标题】:How to validate JSON using System.Text.Json before deserialization 【发布时间】:2021-07-15 19:27:27 【问题描述】:在 .NET Core 5.0 中,使用 System.Text.Json.JsonSerializer Deserialize(someJsonFile) 我得到:
System.Text.Json.JsonException: 'The JSON value could not be converted to System.Guid. Path: $.someGuid | ..
这是预期的,因为 someGuid 属性是 System.Guid 类型,并且 JSON 文件/字符串中 someGuid 的值是:
"someGuid": ""
无法正确反序列化..(因为它不是 Guid.Empty)..
我的问题。
在反序列化之前验证 Json(通常)有什么好的和通用的实现?像 TryParse 或 JsonDocument.Parse?当然,try-catch 但这很脏(恕我直言)。
顺便说一句:我不想使用 Newtonsoft
感谢您的建议(当然还有批评者)。
【问题讨论】:
好像在road-map。有可用的第 3 方解决方案。 我认为你被 try/catch 或为每种类型和一些反序列化验证代码实现自己的转换器卡住了。 【参考方案1】:我使用示例创建了一个自定义转换器,答案是:The JSON value could not be converted to System.Int32
public class StringToGuidConverter : JsonConverter<Guid>
public override Guid Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
if (reader.TokenType == JsonTokenType.String)
ReadOnlySpan<byte> span = reader.ValueSpan;
if (Utf8Parser.TryParse(span, out Guid guid, out int bytesConsumed) && span.Length == bytesConsumed)
return guid;
if (Guid.TryParse(reader.GetString(), out guid))
return guid;
return Guid.Empty;
public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
writer.WriteStringValue(value.ToString());
在我的例子中,我的模型要反序列化为不能采用 Nullable Guid,所以我返回一个空的 GUID,然后在我的逻辑中验证它。
因为我使用 .Net 标准创建了一个 web api,所以我无法在启动类的服务中注册它。但是您可以在调用 Deserialize 方法时使用 JsonSerializerOptions 属性注册自定义转换器,如下所示:
var options = new JsonSerializerOptions
PropertyNameCaseInsensitive = true,
Converters = new NERDS.API.Helpers.StringToGuidConverter()
;
StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream);
string json = reader.ReadToEnd();
return JsonSerializer.Deserialize<T>(json, options);
【讨论】:
以上是关于如何在反序列化之前使用 System.Text.Json 验证 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Protobuf-net r282 在反序列化使用 r249 序列化的对象时遇到问题