以前 .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. nRF51822 硬件复位引脚

    nRF51822 有一个硬件复位引脚和Debug 口SWDIO是共用的,名字叫做nReset. 实现硬件复位是怎样子的: 1.这个引脚引出来, 2.给这个引脚低电平, 3.从低电平拉到高电平,即复位. ...

  2. SSL 安全协议 以及 如何认证

    目录 ssl安全协议 以及 认证 什么是协议 http劫持 ssl是什么 ssl 证书 概念 3种类型ssl 证书 ssl认证:阿里云免费认证 配置 Nginx的ssl认证 nginx的ssl证书(一 ...

  3. Service Fabric独立集群搭建

    开篇声明:巨坑,慎入.若实则无奈,建议直接上azure... 1.  开启服务器自动更新,安装最新的补丁. 2.  下载用于 Windows Server 的 Service Fabric 包(htt ...

  4. SpringBoot dev-tools vjtools dozer热启动类加载器不相同问题

    最近使用唯品会的vjtools的BeanMapper进行对象的深度克隆转换DTO/VO这种操作,Spring Boot的dev-tools热启动,需要把vjtools和dozer包都放到spring- ...

  5. uniapp - 关于ios调试

    [ios调试] 1.一台windows电脑.一根apple数据线(一旦连接以后,apple设备就会自动识别itunes软件,如果没有安装会提示) 2.安装itunes (爱思助手) 3.官方教程:ht ...

  6. 百度开源上传组件webuploader 可上传多文件并带有进度条

    //上传多文件 function UploadMultiFile() { var uploader = WebUploader.create({ // 选完文件后,是否自动上传. auto: true ...

  7. ROS tf-增加坐标系

    博客参考:https://www.ncnynl.com/archives/201702/1312.html ROS与C++入门教程-tf-增加坐标系 说明: 介绍如何为TF增加额外固定的坐标系 为何增 ...

  8. Docker搭建Kafka

    下载Kafka和Zookeeper镜像文件 1,docker pull wurstmeister/kafka 2,docker pull wurstmeister/zookeeper 先运行zk,再运 ...

  9. 使用Fiddler工具发送post请求(带有json数据)以及get请求(Header方式传参)

    Fiddler工具是一个http协议调试代理工具,它可以帮助程序员测试或调试程序,辅助web开发. Fiddler工具可以发送向服务端发送特定的HTTP请求以及接受服务器回应的请求和数据,是web调试 ...

  10. 基于thrift的node.js rpc服务

    1.在node.js 服务下创建node_modules文件,npm install  thrift 下载thrift到该文件下. 2.编写idl文件.user.thrift 内容如下: struct ...