2017-09-24 35 views
1

假设验证码:ASP.NET核心 - 如何认识反序列化已经通过中间件失败

public class Test 
{ 
    public DateTime  Date  { get; set; } 
    public string  Title  { get; set; } 
} 

[HttpPut, Route("test")] 
public IActionResult test([FromBody]Test Data) 
{ 
    .... 
} 

如果用户提供在体内无效JSON,数据将是无效的。

有没有一种方法可以在代码执行之前捕捉到它,所以我不必在每个API方法上测试null值?

我一直在想它可能作为一个中间件可行,但我没有经验,所以我不确定。

+0

您应验证模型数据。如果属性是必需的,你应该标记它们,然后验证过程('ModelState.IsValid')会告诉你它是否正确。 – poke

+0

但这意味着我需要为每个调用添加一个“if(ModelState.IsValid)...”;我试图找到是否可以在管道中捕获并从单个位置返回一个通用错误 – Thomas

回答

1

您可以使用MVC过滤器在执行操作时自动执行验证。引述the documentation

您可以使用动作过滤器,如果状态是无效的自动验证模型的状态,并返回任何错误:

using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Mvc.Filters; 

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

OnActionExecuted方法操作方法运行后,可以看到和通过ActionExecutedContext.Result属性处理操作的结果。如果动作执行被另一个过滤器短路,则ActionExecutedContext.Canceled将被设置为真。如果操作或后续操作过滤器抛出异常,则ActionExecutedContext.Exception将被设置为非空值。将ActionExecutedContext.Exception设置为null会有效'处理'异常,然后将执行ActionExectedContext.Result,就好像它是从操作方法正常返回一样。

+0

实际上,它并不像我预期的那样工作:这迫使我用一个属性来装饰每个调用;但是由于我们有一个可以在很多方面使用的框架,我正在寻找一些完全自动化的东西,并且任何编写新的休息调用的人都不需要考虑。 – Thomas

+0

@Thomas你也可以装饰控制器,将其应用于所有的方法。或者你可以[用'AddMvc'调用全局设置过滤器](https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#filter-scopes-and-order-of-执行)使其适用于所有路线。 – poke

+0

我以前没看到过这个电话!完善!再次感谢! – Thomas