如何忽略坏 JSON 反序列化过程中的异常?

Chr*_*ris 5 c# json asp.net-core system.text.json

我正在使用一个应该返回一个对象的 API,例如

{
    "some_object": { 
        "some_field": "some value" 
    }
}
Run Code Online (Sandbox Code Playgroud)

当该对象为空时,我期望

{
    "some_object": null
}
Run Code Online (Sandbox Code Playgroud)

或者

{
    "some_object": {}
}
Run Code Online (Sandbox Code Playgroud)

但他们发给我的是

{
    "some_object": []
}
Run Code Online (Sandbox Code Playgroud)

...即使它从来不是一个数组。

使用时

JsonSerializer.Deserialize<MyObject>(myJson, myOptions)
Run Code Online (Sandbox Code Playgroud)

[]当出现在预期的位置时会引发异常null

我可以选择性地忽略这个异常吗?

我当前处理此问题的方法是读取 json 并在反序列化之前使用正则表达式修复它。

如果可能的话,我更喜欢使用System.Text.Json,而不引入其他依赖项。

hal*_*ldo 6

此解决方案使用System.Text.JsonJsonConverter中的自定义。

如果some_object是一个数组,那么它将返回一个空对象(如果您愿意,也可以返回 null),并且不会抛出任何异常。否则它将正确反序列化 json。

public class EmptyArrayToObjectConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
    {
        var rootElement = JsonDocument.ParseValue(ref reader);

        // if its array return new instance or null
        if (reader.TokenType == JsonTokenType.EndArray)
        {
            // return default(T); // if you want null value instead of new instance
            return (T)Activator.CreateInstance(typeof(T));               
        }
        else
        {               
            var text = rootElement.RootElement.GetRawText();
            return JsonSerializer.Deserialize<T>(text, options); 
        }
    }

    public override bool CanConvert(Type typeToConvert)
    {
        return true;
    }       

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize<T>(writer, value, options);
    }
}
Run Code Online (Sandbox Code Playgroud)

用属性来装饰你的财产JsonConverter。你的类可能看起来像这样:

public class MyObject
{
    [JsonPropertyAttribute("some_object")]
    [JsonConverter(typeof(EmptyArrayToObjectConverter<SomeObject>))]
    public SomeObject SomeObject { get; set; }

    ...
}
Run Code Online (Sandbox Code Playgroud)