繁体   English   中英

当 Newtonsoft.JSON 反序列化失败时,有没有办法返回自定义错误?

[英]Is there a way to return a custom error when Newtonsoft.JSON deserialization fails?

我想在请求失败时更改 ResponseBody,因为反序列化为 Enum 未成功。 该应用程序是一个 .NET Core 3 API。

我的实体之一具有以下属性:

[JsonConverter(typeof(StringEnumConverter))]
public Attribute Attribute { get; set; }

其中 Attribute 是以下枚举:

public enum Attribute
    {
        [EnumMember(Value = "value-1")]
        value1,
        [EnumMember(Value = "value-2")]
        value2,
        [EnumMember(Value = "some-value")]
        somevalue
    }

当我尝试为 Enum 发布具有错误值的正文时:

{
  "attribute": "wrong-value"
}

我的端点返回一个带有 Newtonsoft 错误的 400,我想返回一个由我创建的 ResponseBody。

{
    "errors": {
        "attribute": [
            "Error converting value \"wrong-value\" to type 'Project.Attribute'. Path 'attribute', line 10, position 24."
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|1cf19d18-4577510ef4de1g923."
}

有没有办法用中间件拦截这样的错误并返回一个自定义的 ResponseBody?

我要做的是创建一个StringEnumConverter类:

internal class StringEnumConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
            try
            {
                return JsonConvert.DeserializeObject<Attribute>("'" + reader.Value.ToString() + "'");
            }
            catch
            {
                var tr = reader as JsonTextReader;
                throw new Exception($"Error converting value \"{reader.Value.ToString()}\" to type \"{objectType.ToString()}\". Path \"{tr.Path}\", line {tr.LineNumber}, position {tr.LinePosition}.");
            }
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

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

然后在尝试反序列化我的 JSON 字符串时,我会捕获任何异常,例如:

string json = "{'attribute': 'value1x'}";

try
{
    MyClass r = JsonConvert.DeserializeObject<MyClass>(json);
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

这样我的 Exception 就会有适当的消息。 当然,您必须记住,这仅用于将字符串反序列化为Attribute类型(也许应该将名称更改为StringToAttributeConverter以提高可读性)。 如果可能,您将不得不为所有不同类型的枚举找到一种稍微更通用的方法(也许通过使用通用...)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM