记录web api的request以及response(即写log)

https://www.cnblogs.com/felixnet/p/5689501.html

https://blog.csdn.net/Vblegend_2013/article/details/83446229

https://stackoverflow.com/questions/27176329/web-api-request-content-empty

https://forums.asp.net/t/2127541.aspx?Get+Http+Raw+Request+and+Response       这个里面提到了DelegatingHandler

https://www.infoworld.com/article/3211590/how-to-log-request-and-response-metadata-in-aspnet-web-api.html   这个里面提到了DelegatingHandler

https://github.com/aspnet/AspNetWebStack/issues/150

 

综合上面几个链接,日志应该使用delegating handler里面处理。(ActionFilter里面,http request的content已经被读取过了,需要像第一个链接里面一样,先重置回去,再读,比较麻烦)

 string requestMessage = requestContent.ReadAsStringAsync().Result; //request raw
            string responseMessage = response.ToString(); //response raw

 

自己写的版本

public class LogHandler : DelegatingHandler
    {
        private string _requestId;
        private readonly string _newLine = Environment.NewLine;

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            _requestId = DateTime.Now.Ticks.ToString();
            var requestBody = request.Content.ReadAsStringAsync().Result;
            LogUtil.CreateLog(LogLevel.Message,
                $"{_requestId}{_newLine}{request.Method.Method} {request.RequestUri.AbsoluteUri} HTTP/{request.Version}{_newLine}{requestBody}");

            var response = await base.SendAsync(request, cancellationToken);
            string responseBody = response.Content.ReadAsStringAsync().Result;
            LogUtil.CreateLog(LogLevel.Message, $"{_requestId}{_newLine}HTTP/{response.Version} {(int)response.StatusCode} {response.StatusCode}{_newLine}{responseBody}{_newLine}{_newLine}");
            return response;
        }
    }

 

 

有ReadAsAsync扩展方法,自动进行类型的转换

  var apiRequest = request.Content.ReadAsAsync<ApiRequest<dynamic>>().Result;
            OwinRequestScopeContext.Current.Items["CountryCode"] = apiRequest.Header.OpCo;

 这个地方如果需要重复读取数据的话

https://stackoverflow.com/questions/26942514/multiple-calls-to-httpcontent-readasasync

If you want to read again and again, you would probably want to read as stream and seek to beginning every time you read the stream.

But then if you want to do what do you now but get the second read working, you can seek to the beginning of the stream, after the first read, like this.

await httpContent.LoadIntoBufferAsync();
var X = await httpContent.ReadAsAsync<T>();

Stream stream = await httpContent.ReadAsStreamAsync();
stream.Seek(0, SeekOrigin.Begin);

var Y = await httpContent.ReadAsAsync<Dictionary<string, object>>();

中间的stream不需要using,否则会遇到这种错误

HTTP/1.1 400 BadRequest
{"Message":"The request is invalid.","ModelState":{"request":["Stream was not readable."]}}

 

转载于:https://www.cnblogs.com/chucklu/p/10438203.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值