如何在TypeConverter中指出错误

时间:2018-04-06 15:19:48

标签: c# asp.net-core error-handling model-binding typeconverter

我正在尝试在ASP.NET Core 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);
}

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

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

1 个答案:

答案 0 :(得分:2)

  

端点的调用者永远不会被告知值是错误的,也不是   我的控制器中的代码是否知道该值是最初的   无效(默认值很容易成为有效值)。

所有模型绑定错误都通过控制器操作中可访问的ControllerBase.ModelState属性进行通信。如果在模型bindingvalidation期间发生某些错误,则ModelStateIsValid属性设置为false

这是一个预期的关注点分离。与您想要的异常冒泡相比,这种方法具有以下优点:

  • 所有操作参数的所有绑定和验证错误都将在ModelState中完全提供。使用异常方法时,只会传达第一个遇到的错误。
  • 异常会破坏请求管道执行。使用ModelState,您可以在以后的管道阶段采取适当的操作,并决定是否仍然可以处理遇到错误的请求。
  • ModelState方法在错误处理方面更灵活。您可以返回适当的响应(例如400 Bad Request或返回带有详细错误说明的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将返回给调用者,控制器操作将不会被调用。

Sample Project on GitHub