以前 .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. SDN初体验(软件定义网络实验一)

    作业说明 本次实验步骤2.3是在机房环境下完成的,步骤1.4是在自己笔记本上重新配置完成的,所以环境.用户名什么的会略有差别. 1. 安装轻量级网络仿真工具Mininet 为了节约课程时间,实验室机房 ...

  2. 安装与配置HSDIS与JITWatch

    本作者的系统: 操作系统版本及位数可通过uname -a命令查看,如下: Linux ubuntu 3.13.0-32-generic #57~precise1-Ubuntu SMP Tue Jul ...

  3. 273道题目;更新到java题目里面 (已迁移到其他类目下面,存储)

    1. Java 基础 1.JDK 和 JRE 有什么区别? 2. == 和 equals 的区别是什么? 3. 两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗? ...

  4. js中isNaN和Number.isNaN的区别

    isNaN 当我们向isNaN传递一个参数,它的本意是通过Number()方法尝试将这参数转换成Number类型,如果成功返回false,如果失败返回true. 所以isNaN只是判断传入的参数是否能 ...

  5. cesium常用设置【转】

    https://blog.csdn.net/D_Walker/article/details/82188514 1.加载线上cesium代码<link href="http://ces ...

  6. ArcGIS 要素类整体平移工具-arcgis/arcpy/模型构建器案例实习教程

    ArcGIS 要素类整体平移工具-arcgis/arcpy/模型构建器案例实习教程 联系方式:谢老师,135-4855_4328,xiexiaokui#qq.com 目的:对整个要素类,按指定偏移距离 ...

  7. slot 插槽子组件向父组件传值

    slot 插槽要实现子组件向父组件传值,则需要运用 作用域插槽 1.父组件中用 标签加上 slot-scoped 的属性,属性值随性.(旧版本是scope,vue新版本必须用slot-scope) 2 ...

  8. powshell 输出字符编码的问题,设置为utf-8

    https://blog.csdn.net/qianxiao_1/article/details/79463409 $PSDefaultParameterValues['Out-File:Encodi ...

  9. pandas filter数据筛选

    https://study.163.com/course/courseMain.htm?courseId=1006383008&share=2&shareId=400000000398 ...

  10. git 项目最常用命令总结

    本文为博主原创,未经允许不得转载: 1.查看git基础配置信息 1.查看用户名和邮箱地址 git config user.name   git config user.email 2.修改用户名和邮箱 ...