如何使用 [FromBody] 忽略 json 反序列化中的错误?

Eug*_*ene 5 c# asp.net-core asp.net-core-3.0

我使用 asp net core 3.0,但有问题:

模型:

public class Location
{
    public string Name { get; set; }
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器中的方法

[HttpPost("api/somePost")]
public Task Test([FromBody] Location location)
{
    // Do somethimg
    return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)

启动:

services.AddMvc().AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.Error = (sender, args) =>
            {
                args.ErrorContext.Handled = true;
            };
        });
Run Code Online (Sandbox Code Playgroud)

我用邮递员发送json

邮递员请求

并在控制器方法的位置参数中获取空值!

错误处理程序

控制器方法

如何忽略类型转换错误并在“经度”属性中获取默认值 (0)?

GTH*_*ten 1

听起来您需要一个自定义转换器(正如评论中也提到的)。

public class YourCustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsAssignableFrom(typeof(double));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return serializer.Deserialize<double>(reader);
        }
        catch
        {
            return 0d;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您只需使用 来装饰您希望其有效的属性JsonConverter。对于您的示例,它看起来像这样:

public class Location
{
    public string Name { get; set; }

    [JsonConverter(typeof(YourCustomConverter))]
    public double Latitude { get; set; }

    [JsonConverter(typeof(YourCustomConverter))]
    public double Longitude { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您发送无效数据,反序列化器将引发异常,该异常将由返回的自定义转换器捕获0(或您希望它是任何值)。

更新:

免责声明:这未经测试!

您可能可以制作一个通用转换器来处理所有情况:

public class YourCustomConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsAssignableFrom(typeof(T));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return serializer.Deserialize<T>(reader);
        }
        catch
        {
            return default(T);
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以将其用作属性[JsonConverter(typeof(YourCustomConverter<double>)]

还有一个选项可以使用自定义转换器来使用以下代码进行所有 JSON 序列化/反序列化:

services.AddMvc().AddNewtonsoftJson(options =>
{
    // Configure a custom converter
    options.SerializerOptions.Converters.Add(new SomeOtherCustomJsonConverter());
});
Run Code Online (Sandbox Code Playgroud)

但是,这并不能真正变得通用,因此您必须编写自己的所有可能类型的处理。