如何指示 TypeConverter 中的错误

How do I Indicate an Error in a TypeConverter

我正尝试在 ASP.NET 核心 2 中做一些 model binding on simple types with TypeConverter,即将 string 转换为我的自定义类型。

如果字符串格式不对,我想指出,例如通过抛出异常:

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
    if (value is string s)
    {
        var result = Parse(s);

        if (!result.Success)
        {
            throw new ArgumentException("Invalid format", nameof(value), result.Exception);
        }

        return result.Value;

    }

    return base.ConvertFrom(context, culture, value);
}

目前似乎异常被简单地吞没并忽略了,将绑定值保留为默认值。 端点的调用者永远不会被告知该值是错误的,我在控制器中的代码也不知道该值最初是无效的(默认值很容易成为有效值)。

如果格式无效,我希望转换失败,但我该怎么做?

The caller of the endpoint is never told that the value is wrong, nor does my code in the controller know that the value was originally invalid (the default value could easily be a valid value).

所有模型绑定错误都通过 ControllerBase.ModelState 属性 在控制器操作中访问。 ModelState 已将 IsValid 属性 设置为 false 如果在模型 binding or validation 期间发生某些错误。

这是一种有意的关注点分离。与随心所欲的异常冒泡相比,这种方法有以下优点:

  • 所有操作参数的所有绑定和验证错误将在 ModelState 中一起提供。使用异常方法只会传达第一个遇到的错误。
  • 异常将中断请求管道的执行。使用 ModelState,您可以在以后的管道阶段采取适当的操作,并决定是否仍然可以处理遇到错误的请求。
  • ModelState 方法在错误处理方面更加灵活。您可以 return 适当的响应(例如 400 Bad Request 或 return HTML 查看详细的错误描述)。

处理无效模型状态的最基本方法是通过检查 ModelState.IsValid 值的瘦操作过滤器:

public class CheckModelStateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
    }
}

正在 Startup.ConfigureServices():

中注册过滤器
services.AddMvc(options =>
{
    options.Filters.Add(new CheckModelStateAttribute());
});

在模型绑定错误的情况下,HTTP 错误代码 400 Bad Request 将 return 发送给调用者,控制器操作将不会被调用。

Sample Project on GitHub