简体   繁体   English

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

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

I want to change the ResponseBody when a request fails because deserialization to an Enum wasn't successful.我想在请求失败时更改 ResponseBody,因为反序列化为 Enum 未成功。 The application is a .NET Core 3 API.该应用程序是一个 .NET Core 3 API。

I've got the following property on one of my entities:我的实体之一具有以下属性:

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

where Attribute is the following Enum:其中 Attribute 是以下枚举:

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

When I try to POST a body with a wrong value for the Enum:当我尝试为 Enum 发布具有错误值的正文时:

{
  "attribute": "wrong-value"
}

My endpoint returns a 400 with a Newtonsoft error and I'd like to return a ResponseBody created by me instead.我的端点返回一个带有 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."
}

Is there a way to intercept such error with a middleware and return a custom ResponseBody?有没有办法用中间件拦截这样的错误并返回一个自定义的 ResponseBody?

What I would do is to create a StringEnumConverter class:我要做的是创建一个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;
    }
}

And then while trying to deserialize my JSON string I would catch any exception like:然后在尝试反序列化我的 JSON 字符串时,我会捕获任何异常,例如:

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

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

That way my Exception would have the appropriate message.这样我的 Exception 就会有适当的消息。 Of course, you have to keep in mind that this is only for deserializing strings to the Attribute type (perhaps the name should be changed to StringToAttributeConverter for more readability).当然,您必须记住,这仅用于将字符串反序列化为Attribute类型(也许应该将名称更改为StringToAttributeConverter以提高可读性)。 You will have to find a slightly more generic way of doing it for all different types of enums (maybe by using a generic...) if possible.如果可能,您将不得不为所有不同类型的枚举找到一种稍微更通用的方法(也许通过使用通用...)。

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

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