以前 .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. App数据指标

    App数据指标 1 App数据指标 2 参考资料 超详细的APP数据指标体系分析

  2. md5加密后不能解密

    MD5加密原理是散列算法,散列算法也称哈希算法.计算机专业学的数据结构就有哈希表这一知识点.比如10除以3余数为一,4除以3余数也为一,但余数为一的就不知道这个数是哪个了.所以md5不能解密.就算是设 ...

  3. 第09组 Beta冲刺(1/4)

    队名:软工9组 组长博客:https://www.cnblogs.com/cmlei/ 作业博客:https://edu.cnblogs.com/campus/fzu/SoftwareEngineer ...

  4. windows命令行查看文件MD5

    certutil -hashfile D:\1.exe MD5certutil -hashfile D:\1.exe SHA1certutil -hashfile D:\1.exe SHA256 原文 ...

  5. Java实现批量将word文档转换成PDF

    先导入words的jar包 需要jar包的私聊我发你 代码如下:import com.aspose.words.Document;import java.io.File; public class W ...

  6. 错误: -source 1.6 中不支持 diamond 运算符

    问题 错误: -source 1.6 中不支持 diamond 运算符 解决步骤 1.检查ide的默认编译环境 ,快捷键ctrl + alt +s 找Java Compiler ,发现设置是 Targ ...

  7. Linux-flock文件锁的使用

    在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock. flock,建议性锁,不具备强制性.一个进程使用 ...

  8. Wise Force Deleter 强制删除文件工具

    https://www.xitmi.com/3321.html   Wise Force Deleter v1.49 中文绿色版 强制删除文件工具

  9. (4)Flask项目模板渲染初体验

    一.准备静态资源 将项目使用到的静态资源拷贝到static目录 二.创建前台首页html 创建templates/home/home.html页面,内容包含导航和底部版权两部分,中间内容区域为模板标签 ...

  10. ISO/IEC 9899:2011 条款6.10——预处理指示符

    6.10 预处理指示符 语法 1.preprocessing-file: groupopt group: group-part group    group-part group-part: if-s ...