问题描述
当由于对Enum的反序列化失败而导致请求失败时,我想更改ResponseBody。该应用程序是.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
}
{
"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);
}
这样,我的异常将具有适当的消息。当然,您必须记住,这仅是为了将字符串反序列化为Attribute
类型(也许名称应更改为StringToAttributeConverter
以提高可读性)。如果可能的话,您将必须找到一种针对所有不同类型的枚举的通用方法(也许使用通用...)。