【问题标题】:How to trace each request ASP.NET Web API with NLog如何使用 NLog 跟踪每个请求 ASP.NET Web API
【发布时间】:2016-08-19 06:46:43
【问题描述】:

我使用 ASP.NET Web API 创建了一个简单的 REST API。 出于测试目的,我想添加一些跟踪。所以我将 NLog 添加到我的项目中。此时我的日志是这样的:

// POST api/values
public void Post([FromBody]string value)
{
    logger.Trace("Request: {0} api/values", Request.Method); 
    _repository.insert(value);
    logger.Trace("Response: {0} api/values", Request.Method); 
}

在每个方法中,我在方法的顶部和底部添加了一个 logger.Trace。我对这种方法有 2 个问题:

  1. 我需要记住将这些行添加到我的每个方法中
  2. 我不知道如何将 JSON 正文添加到我的跟踪中

第 1 点目前还不是真正的问题(见下文),但我很快需要一些东西来检查我的 API 收到的每个 JSON 正文。

我已经试过了

// POST api/values
public void Post([FromBody]string value)
{
    logger.Trace("Request: {0} api/values {1}", Request.Method, Request.Body); 
    _repository.insert(value);
    logger.Trace("Response: {0} api/values", Request.Method); 
}

但是 Request 上没有 Body 属性。

我还为我的观点找到了一个有趣的文档 1:http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi

【问题讨论】:

  • 我已经阅读了很多关于 Trace 的文档,但其中大多数都解释了如何使用 Trace,而不是如何进行 Trace,或者完全是错误的。例如,我从论坛中找到了这个解决方案字符串 val = Request.Form["SGEmail"] ,但这是错误的。没有这样的 Requet.Form 属性。
  • Request.Form 包含页面中
    标记中的任何内容。 SGEmail 值对某些网页是特殊的,任何 Request.Form 值也是如此。

标签: c# asp.net json nlog


【解决方案1】:

这就是你的动作过滤器......在动作方法执行/执行之前/之后做某事

public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        //Do something here before an action method starts executing
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
    {
        //Do something here after an action method finished executing
    }
}

然后,您需要将此过滤器插入 asp.net 管道...当应用程序启动时,无论您使用 owin/katana 还是 global.asax 都没有关系...

GlobalConfiguration.Configuration.Filters.Add(new MyCustomFilter());

上面的行会将该过滤器添加到所有操作方法中。如果您想关闭某些操作方法的跟踪,只需将标志/开关属性添加到操作过滤器,以便您可以关闭某些操作的跟踪...

public class MyCustomFilter : System.Web.Http.Filters.ActionFilterAttribute
{
    public bool DisableTracing{get;set;}

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if(!DisableTracing){
               //Do something here before an action method starts executing
        }
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context)
    {
        if(!DisableTracing){
               //Do something here before an action method starts executing
        }
    }
}

现在您可以将其关闭控制器操作...

[MyCustomFilter(DisableTracing = true)]
public IHttpActionResult MyAction(int id){}

更新

要从请求的正文中读取 JSON 对象,只需读取请求的内容,如下所示...

 request.Content.ReadAsStringAsync().Result;

【讨论】:

  • 我刚刚发布了我的解决方案。您的仅适用于 ActionResult,而我使用 HTTP REST (JSON) 请求。我想知道...我做错了什么还是我的解决方案实际上是我对 HTTP 请求所需要的?你也不需要调用 MyCustomFilter --> MyCustomFilterAttibute 吗?以属性结尾作为属性使用?
【解决方案2】:

Leo 的解决方案似乎对 MVC 是正确的,但对于 Http REST API,我必须实现来自 http://www.c-sharpcorner.com/UploadFile/1492b1/restful-day-sharp6-request-logging-and-exception-handingloggin/ 的解决方案

public class HttpLoggingFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
    {
        //Do something here
    }

    public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
    {
        //Do something here
    }
}

在我的代码上测试了这两种方法后,我可以看出 Leo 的代码是在页面刷新位上执行的,而不是在简单的 REST 请求上执行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多