无法在http请求上捕获HttpMethod:OPTIONS

时间:2018-11-20 08:32:07

标签: c# asp.net-web-api asp.net-core .net-core actionfilterattribute

我正在编写一个ActionFilterAttribute,在其中检查userId路由/查询参数并将其与jwt令牌的主题进行比较。我注意到动作过滤器被触发两次。在chrome中,我可以看到一个OPTIONS请求已发送到服务器,在调试控制台的输出中,我可以看到使用正确的http方法的调用:

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 OPTIONS http://localhost:5000/api/v1/users/33417
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/api/v1/users/33417 application/json

但是当它到达我的动作过滤器时,Http方法始终设置为GET,因此我无法在OPTIONS调用中使过滤器返回。

这是一个基本的OnActionExecutionAsync覆盖方法:

    public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        Debug.WriteLine("URL CALL: " + context.HttpContext.Request.GetDisplayUrl());
        Debug.WriteLine("HTTP METHOD: " + context.HttpContext.Request.Method);
        if (HttpMethods.IsOptions(context.HttpContext.Request.Method))
        {
            Debug.WriteLine("HTTP METHOD: OPTIONS");
            return base.OnActionExecutionAsync(context, next);
        }
        // Other Code ....
    }

调试日志:

URL CALL: http://localhost:5000/api/v1/users/33417
HTTP METHOD: GET 
URL CALL: http://localhost:5000/api/v1/users/33417 
HTTP METHOD: GET

另一个有趣的一点是,如果我从Postman工具请求选项,我的API会返回以下错误消息:

{
    "error": {
        "code": "UnsupportedApiVersion",
        "message": "The HTTP resource that matches the request URI 'http://localhost:5000/api/v1/users/33417' with API version '1' does not support HTTP method 'OPTIONS'.",
        "innerError": null
    }
}

这是我在启动中的Cors配置:

services.AddCors(options => options.AddPolicy(_constants.CorsPolicy,
                builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials()
                    .Build()));

有什么办法可以在我的动作过滤器中捕获OPTIONS http方法?

1 个答案:

答案 0 :(得分:1)

由于您在应用上设置了CORS, 它在MVC之前响应OPTIONS飞行前请求。 该请求永远不会到达MVC,因此您的过滤器看不到它。 您的过滤器看到的是在OPTIONS请求之后出现的GET请求。

app.UseCors(); //Sees OPTIONS request, sets response and returns

app.UseMvc();