【问题标题】:How do I log a non GET request to my action method?如何将非 GET 请求记录到我的操作方法?
【发布时间】:2016-06-06 23:39:24
【问题描述】:

我的操作方法设置为只接受 GET 请求。如果向其发送除 GET 之外的动词,则会将“HTTP 405 Method not allowed”响应发送回客户端。但是每当向它发送除 GET 之外的动词时,我都需要记录它。我目前正在尝试的方式是尝试引发异常(我不知道要捕获哪个异常),然后在 catch 块内进行日志记录。我的操作方法如下:

[RoutePrefix("api/Resource")]
public class MyController : ApiController
{
.
.
.
    [Route("MyRoute")]
    [ResponseType(typeof(IEnumerable<MyResource>))]
    [HttpGet]
    public async Task<IHttpActionResult> GetMyResourceAsync()
    {
        try
        {
            .
            .
            .
        }
        catch (WhichException e) // which exception do I catch here if a verb other than GET is sent by a client?
        {
            MyLogger.Log("Invalid http verb!");
        }

    }
.
.
.
}

当我尝试使用 postman 访问资源并指定诸如 POST 或 PUT 之类的动词时,我收到 HTTP 405 响应,但我不确定在我的操作方法中捕获哪个异常以拦截非 GET 请求.不一定是通过引发异常,但任何其他记录非 GET 请求的方式也可以。

【问题讨论】:

  • 你不需要捕获异常。如果使用了另一个动词,您的 GET 服务将不会执行。
  • 我知道它不会被执行,但我需要记录来自客户端的所有非 GET 请求。我该怎么做?
  • Bruno.P 是正确的。我已经添加了一个记录请求的答案......如果你的“规则”不是 Http.Get 请求......过滤起来很简单。

标签: asp.net-web-api httpverbs


【解决方案1】:

如 cmets 中所述,如果您有一个 Http.Get(webapi 方法),并且您发送了一个 POST,那么该方法将永远不会触发。 您可能缺少的是 Http.Get 是默认值。

您可能还想查看对 REST 的基本理解。

http://encosia.com/rest-vs-rpc-in-asp-net-web-api-who-cares-it-does-both/

当您的控制器运行时,它是方法“类型”(GET、POST、PUT、DELETE) MethodName(微软为您处理)的组合)...调用方法。

因此,一个用[HttpGet] 装饰的方法(或者因为没有应用属性......然后默认为 HttpGet)永远不会为 POST 请求触发(发送来自客户)。所以你的“捕捉错误方法”的概念在 WebApi 世界中没有意义。

这里有一个更好的解决方案:

考虑编写一个 ActionFilter

这是一个简单的(显示 Request.Method)(显然,您可以过滤非 GET 请求的 Request.Method):

 public class MyActionFilter : System.Web.Http.Filters.ActionFilterAttribute     /* from #region Assembly System.Web.Http.dll, v4.0.0.0     // C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC     4\Assemblies\System.Web.Http.dll     #endregion */
 {
    public MyActionFilter()
    {
    }


    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        Console.WriteLine("OnActionExecuting:" + actionContext.Request.Method);
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        Console.WriteLine("OnActionExecuted:" + actionExecutedContext.Request.Method);
    }
}

您可以将过滤器应用于:

一种方法

与/或

A(webapi)控制器(提示,如果你想将它添加到 N 个“你的”Api 控制器中,创建一个基本(抽象)控制器,将属性添加到该控制器并从基本控制器继承特定控制器/抽象控制器)

“全局”与

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
    config.Routes.Blah.Blah.Blah; /* already existing code */

    /* this is the new code you need to add (line below) */
    config.Filters.Add(new MyActionFilter());
}

【讨论】:

  • 非常感谢您的想法,我现在正在尝试,如果我能够成功捕获非 GET 请求,我会通知您
  • 再问一个问题 - 除了操作过滤器,您认为使用自定义消息处理程序也可以实现同样的效果吗?
  • 您可以添加自定义委托处理程序.......PRO 它在管道的早期。 CON 它是一个“全局唯一”的东西......又名,你不能将它缩小到一个单一的控制器或方法。您通常会添加一些“忽略此 AbsoluteUri”技巧来忽略某些请求。
  • 好的,我的 API 中有一些方法可以发送 POST 或 PUT 动词,但其他一些方法应该只接受 GET 动词。在这种情况下,自定义处理程序是否会阻止所有非 GET 请求,即使是那些可以使用它们的方法?如果是这样,我可以向处理程序提供某种配置以排除这些 uris 吗?
  • 不知道。你必须证明它的概念。但是你现在有工具来做你需要做的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 2020-08-25
  • 2018-01-15
相关资源
最近更新 更多