以前 .NET Framework WebApi 记录接口访问日志,一般是通过Filter的方式进行拦截,通过重写ActionFilterAttribute的OnActionExecuting实现拦截记录Request内容,通过重写OnActionExecuted实现拦截记录Response内容,具体实现代码就不贴了。这篇简单介绍.Net Core WebApi 下通过中间件的拦截方式记录接口访问日志,关键部分是通过读取获取 Request.Body 时需要开启 Request.EnableRewind () 启用倒带功能;读取 Response.Body 时需要用到的技巧,详细看代码。该例子中我使用的日志组件是Log4Net,获取到的信息通过Log4Net保存到本地文件。

创建日志类

using System;
using System.Collections.Generic;
using System.Linq; namespace DYDGame.Web.Host
{
public class RequestResponseLog
{
public string Url {get;set;}
public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
public string Method { get; set; }
public string RequestBody { get; set; }
public string ResponseBody { get; set; }
public DateTime ExcuteStartTime { get; set; }
public DateTime ExcuteEndTime { get; set; }
public override string ToString()
{
string headers = "[" + string.Join(",", this.Headers.Select(i => "{" + $"\"{i.Key}\":\"{i.Value}\"" + "}")) + "]";
return $"Url: {this.Url},\r\nHeaders: {headers},\r\nMethod: {this.Method},\r\nRequestBody: {this.RequestBody},\r\nResponseBody: {this.ResponseBody},\r\nExcuteStartTime: {this.ExcuteStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")},\r\nExcuteStartTime: {this.ExcuteEndTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
}
}
}

创建记录接口日志中间件 Middleware

using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Threading;
using DYDGame.Utility;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging; namespace DYDGame.Web.Host {
public class RequestResponseLoggingMiddleware {
private readonly RequestDelegate _next;
private RequestResponseLog _logInfo; public RequestResponseLoggingMiddleware (RequestDelegate next) {
_next = next;
} public async Task Invoke (HttpContext context) {
_logInfo = new RequestResponseLog (); HttpRequest request = context.Request;
_logInfo.Url = request.Path.ToString ();
_logInfo.Headers = request.Headers.ToDictionary (k => k.Key, v => string.Join (";", v.Value.ToList ()));
_logInfo.Method = request.Method;
_logInfo.ExcuteStartTime = DateTime.Now; //获取request.Body内容
if (request.Method.ToLower ().Equals ("post")) { request.EnableRewind (); //启用倒带功能,就可以让 Request.Body 可以再次读取 Stream stream = request.Body;
byte[] buffer = new byte[request.ContentLength.Value];
stream.Read (buffer, , buffer.Length);
_logInfo.RequestBody = Encoding.UTF8.GetString (buffer); request.Body.Position = ; } else if (request.Method.ToLower ().Equals ("get")) {
_logInfo.RequestBody = request.QueryString.Value;
} //获取Response.Body内容
var originalBodyStream = context.Response.Body; using (var responseBody = new MemoryStream ()) {
context.Response.Body = responseBody; await _next (context); _logInfo.ResponseBody = await FormatResponse (context.Response);
_logInfo.ExcuteEndTime = DateTime.Now;
Log4Net.LogInfo ($"VisitLog: {_logInfo.ToString()}"); await responseBody.CopyToAsync (originalBodyStream);
}
} private async Task<string> FormatResponse (HttpResponse response) {
response.Body.Seek (, SeekOrigin.Begin);
var text = await new StreamReader (response.Body).ReadToEndAsync ();
response.Body.Seek (, SeekOrigin.Begin); return text;
}
} public static class RequestResponseLoggingMiddlewareExtensions {
public static IApplicationBuilder UseRequestResponseLogging (this IApplicationBuilder builder) {
return builder.UseMiddleware<RequestResponseLoggingMiddleware> ();
}
}
}

把中间件添加到管道中 Pipeline

在 Startup.cs 添加
        public void Configure (IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
if (env.IsDevelopment ()) {
app.UseDeveloperExceptionPage ();
} else {
app.UseHsts ();
} loggerFactory.AddLog4Net ();
app.UseRequestResponseLogging(); // app.UseHttpsRedirection();
app.UseMvc ();
}

ASP.NET Core 入门(2)(WebApi接口请求日志 Request和Response)的更多相关文章

  1. ASP.NET Core 入门教程 10、ASP.NET Core 日志记录(NLog)入门

    一.前言 1.本教程主要内容 ASP.NET Core + 内置日志组件记录控制台日志 ASP.NET Core + NLog 按天记录本地日志 ASP.NET Core + NLog 将日志按自定义 ...

  2. Asp.net Core 入门实战

    Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个合集,方便一次性Clone 目录 快速入门 安装 一个最小的应用 项目模板 路由 静态文件 ...

  3. ASP.NET CORE 入门教程(附源码)

    ASP.NET CORE 入门教程 第一课 基本概念 基本概念 Asp.Net Core Mvc是.NET Core平台下的一种Web应用开发框架 符合Web应用特点 .NET Core跨平台解决方案 ...

  4. ASP.NET Core应用针对静态文件请求的处理[4]: DirectoryBrowserMiddleware中间件如何呈现目录结构

    和StaticFileMiddleware中间件一样,DirectoryBrowserMiddleware中间本质上还是定义了一个请求地址与某个物理目录之间的映射关系,而目标目录体现为一个FilePr ...

  5. ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求

    我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMidd ...

  6. ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件

    虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件 ...

  7. asp.net core系列 38 WebAPI 返回类型与响应格式--必备

    一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...

  8. asp.net core系列 37 WebAPI 使用OpenAPI (swagger)中间件

    一.概述 在使用Web API时,对于开发人员来说,了解其各种方法可能是一项挑战.在ASP.NET Core上,Web api 辅助工具介绍二个中间件,包括:Swashbuckle和NSwag .NE ...

  9. ASP.NET Core入门(一)

    大家好,很荣幸您点了开此篇文章,和我一起来学习ASP.NET Core,此篇文字为<ASP.NET Core入门>系列中的第一篇,本系列将以一个博客系统为例,从第一行代码,到系统发布上线( ...

随机推荐

  1. 38861cba61c66739c1452c3a71e39852.ttf net::ERR_ABORTED 404 (Not Found)

    error: http://localhost:63342/clappr-dev/js/38861cba61c66739c1452c3a71e39852.ttf net::ERR_ABORTED 40 ...

  2. QML学习(三)——<QML命名规范>

    QML对象声明 QML对象特性一般使用下面的顺序进行构造: id 属性声明 信号声明 JavaScript函数 对象属性 子对象 状态 状态切换 为了获取更好的可读性,建议在不同部分之间添加一个空行. ...

  3. CSS系列之后代选择器、子选择器和相邻兄弟选择器

    后代选择器比子选择器的范围大,包含子选择器,且包含子选择器的“子孙”选择器,后代选择器使用"空格"符号间隔选择器 子选择器:子选择器只是父选择器的一级子元素,使用"> ...

  4. Linux 上配置 SQL Server Always On Availability Group

    SQL Server Always On Availability Group 配置步骤:配置三台 Linux 集群节点创建 Availability Group配置 Cluster Resource ...

  5. 帝国CMS 7.5编辑器从WORD中粘贴过来无法保留格式和图片的解决办法

      配置过滤js文件 首先打开  \editor\plugins\pastefromword\filter\default.js  在文件的最后部分又如下代码(修改前的代码),也可以搜索CKEDITO ...

  6. Redis代码示例

    RedisTemplate 如果想要在java中使用Redis相关的数据结构,要先注入RedisTemplate. @Autowired private RedisTemplate<K,V> ...

  7. Web前端开发规范之文件存储位置规范

    文件存放位置规范 1   文件夹说明 flash存放flash文件 p_w_picpaths存放图片文件 inc存放include文件 library存放DW库文件 media存放多媒体文件 scri ...

  8. Spring MVC JSON乱码问题

    之前项目中也遇到过返回JSON时乱码问题,当时找到了一个方法解决了问题但是没有明白原因,今天这个项目又遇到了JSON乱码问题,用之前的方法不行,看了这篇博文才明白为什么 @RequestMapping ...

  9. tomcat启动慢的解决办法

    SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generatio ...

  10. Python3基础 yield next 获取生成器生出的值

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...