需要将asp.net webapi 2请求和响应主体记录到数据库中

use*_*985 96 c# asp.net-web-api

我正在使用IIS上托管的Microsoft Asp.net WebApi2.我非常想简单地记录每个帖子的请求体(xml或json)和响应体.

这个项目或处理帖子的控制器没什么特别之处.我对使用nLog,elmah,log4net等日志框架或webapi的内置跟踪功能不感兴趣,除非有必要这样做.

我只是想知道在哪里放置我的日志代码以及如何从传入和传出的请求和响应中获取实际的json或xml.

我的控制器发布方法:

public HttpResponseMessage Post([FromBody])Employee employee)
{
   if (ModelState.IsValid)
   {
      // insert employee into to database
   }

}
Run Code Online (Sandbox Code Playgroud)

Sof*_*tor 180

我建议使用DelegatingHandler.然后,您无需担心控制器中的任何日志记录代码.

public class LogRequestAndResponseHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // log request body
        string requestBody = await request.Content.ReadAsStringAsync();
        Trace.WriteLine(requestBody);

        // let other handlers process the request
        var result = await base.SendAsync(request, cancellationToken);

        if (result.Content != null)
        {
            // once response body is ready, log it
            var responseBody = await result.Content.ReadAsStringAsync();
            Trace.WriteLine(responseBody);
        }

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

只需Trace.WriteLine用您的日志代码替换并注册处理程序,WebApiConfig如下所示:

config.MessageHandlers.Add(new LogRequestAndResponseHandler());
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常酷的解决方案,但是当响应不包含正文时会抛出错误.但这很容易检查和修复:) (7认同)
  • @SoftwareFactor:`ContinueWith`和`Result`是危险的API.使用`await`代替它会好得多,即`var result = await base.SendAsync(request,cancellationToken); var resposeBody = await response.Content.ReadAsStringAsync(); Trace.WriteLine(responseBody); 回复;` (4认同)
  • 调用`await request.Content.ReadAsStringAsync();`是否导致错误,说明在某些情况下已经读取了请求流? (4认同)
  • 如果委托处理程序读取请求的主体,它是否会使实际的终端处理程序(即mvc/webapi)不可用? (4认同)
  • `task.Result.Content`返回`System.Net.Http.ObjectContent`.有没有办法获得原始的xml/json? (3认同)
  • 文章[这里](https://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi)给出了很好的解释 (3认同)

Ven*_*ndi 14

有多种方法可以为每个WebAPI方法调用一般地处理请求/响应日志记录:

  1. ActionFilterAttribute:可以编写自定义ActionFilterAttribute并装饰控制器/操作方法以启用日志记录.

    Con:你需要装饰每个控制器/方法(你仍然可以在基础控制器上完成它,但它仍然不能解决交叉问题.

  2. 覆盖BaseController并处理日志记录.

    Con:我们期待/强制控制器继承自定义基本控制器.

  3. DelegatingHandler.

    优点:我们没有采用这种方法来触及控制器/方法.委托处理程序处于隔离状态,可以正常处理请求/响应日志记录.

有关更深入的文章,请参阅http://weblogs.asp.net/fredriknormen/log-message-request-and-response-in-asp-net-webapi.


Pre*_*k K 11

您拥有的一个选项是使用创建动作过滤器并使用它来装饰WebApiController/ApiMethod.

过滤属性

public class MyFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.Request.Method == HttpMethod.Post)
            {
                var postData = actionContext.ActionArguments;
                //do logging here
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

WebApi控制器

[MyFilterAttribute]
public class ValuesController : ApiController{..}
Run Code Online (Sandbox Code Playgroud)

要么

[MyFilterAttribute]
public void Post([FromBody]string value){..}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 我想每次有人发布时都记录请求和响应数据。 (3认同)
  • 您可以使用OnActionExecuted并尝试“((actionExecutedContext.ActionContext.Response.Content as ObjectContent).Value.ToString()”)来获取响应并将其记录下来。 (2认同)