前言:从2019年年中入坑.net core已半年有余,总体上来说虽然感觉坑多,但是用起来还是比较香的。本来我是不怎么喜欢写这类实践分享或填坑记录的博客的,因为初步实践坑多,文章肯定也会有各种错误,跟别人优秀的文章比起来,好像我写的东西没有什么存在的价值。但是入坑.net core以来,这种思想开始慢慢改变了,毕竟我依靠别人解决问题的文章也不尽是教科书般的存在,但是很使用。所以,把自己的实践过程记录出来,一方面是巩固和完善自己的技术栈,另一方能帮助到其他人,或者跟他人共同探讨,也不算闭门造轮子,自娱自乐了吧。.net core web api的实践记录,就由中间件的使用开始吧。

1、必要的知识储备

在阅读这篇文章的时候,我希望读者已经了解接口的逆变与协变、泛型、委托等知识点(个人认为这是了解.net各种框架的必备知识),同时也知道.net core的依赖注入、生命周期的相关内容(园子里前几名的大佬,对这块都有非常优秀的讲解,这里我就不作介绍,有需要的童鞋可以留言,我提供连接)。

2、.net core webapi项目中配置中间件

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMiddleware<RequestMiddleware>();
app.UseMvc();
}

  在项目的Startup.cs文件中,找到Configure方法,加上app.UseMiddleware<RequestMiddleware>(); 这里的RequestMiddleware就是自定义的中间件,我们可以简单看下UseMiddleware的定义:

TMiddleware是一个泛型,使用UseMiddleware传递的就是自定义的中间件。

3、自定义中间件的实现

很遗憾我的反编译工具未能找到UseMiddleware的实现方法,但是结合官网上的介绍https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/write?view=aspnetcore-3.1),自定义的中间件需要构造函数来接收一个RequestDelegate对象,是关于HttpRequest的一个委托,另外还需要一个名为 Invoke 或 InvokeAsync 的公共方法,用于写一些HttpRequest的预处理逻辑。在我的项目中,我用它来进行参数预处理、登录预处理、Session预处理以及请求的转发功能。

public class RequestMiddleware
{
private readonly RequestDelegate _next;
private readonly IConfig config; public RequestMiddleware(RequestDelegate next, IConfig config)
{
_next = next;
this.config = config;
} public Task Invoke(HttpContext context)
{
context.Request.EnableRewind(); //支持context.Request.Body重复读取,内部调用了EnableBuffering方法,否则在使用部分方法或属性时会报错误System.NotSupportedException: Specified method is not supported,例如context.Request.Body.Position
// && context.Request.Path.Value == "/api/Main"
if (context.Request.ContentLength != null)
{
Stream stream = context.Request.Body;
byte[] buffer = new byte[context.Request.ContentLength.Value];
stream.Read(buffer, 0, buffer.Length);
string querystring = Encoding.UTF8.GetString(buffer); RequestMiddleParam requestEntity = Newtonsoft.Json.JsonConvert.DeserializeObject<RequestMiddleParam>(querystring);
if (requestEntity == null)
{
throw new Exception("无法处理的请求");
} string param = Newtonsoft.Json.JsonConvert.SerializeObject(requestMiddleMapParam); //参数
//todo 参数校验
byte[] bs = Encoding.UTF8.GetBytes(param); //参数转化为utf8码 //context.Request.Body.Seek(0, SeekOrigin.Begin);
//context.Request.EnableBuffering(); var ms = new MemoryStream();
context.Request.Body = ms;
context.Request.Body.Write(bs, 0, bs.Length); context.Request.Body.Position = 0; //重置context.Request.Body的Stream指针,否则报A non-empty request body is required.错误
} // Call the next delegate/middleware in the pipeline
return this._next(context);
}
}

  值得注意的是,构造函数可以使用Startup.cs中ConfigureServices方法里的注入项,上面实例代码中的IConfig就是的。(这里还有一个坑,就是中间件通过构造函数来接收services.AddDbContext的注入项,因为生命周期不一样)

4、参数预处理遇到的坑

以一个Post请求为例,参数是Json结构,为了判断Json参数中的某字段是否符合规则,就需要对其进行反序列化,校验完成后,再序列化填进Body对象中。这里注意下context.Request.EnableRewind();与context.Request.Body.Position = 0;两行代码的添加,因为是以流的形式读取和再写入参数,EnableRewind方法支持重复读取,而context.Request.Body.Position的归0则保证在重新将参数写入Body后,报A non-empty request body is required.错误。

以上就是.net core中间件的简单介绍了,其实它的作用有些像asp.net的拦截器,将请求拦截做一些预处理,针对请求参数的处理、服务的转发,甚至登录校验等需求,都是个不错的选择。如果还想深入了解的同学,可自行去寻找UseMiddleware的实现方式。下一篇文章,我将介绍使用.net core + Redis + Session完成分布式Session共享时遇到的坑,欢迎大家共同探讨。

.Net Core Web Api实践之中间件的使用(一)的更多相关文章

  1. .Net Core Web Api实践(三).net core+Redis+docker实现Session共享

    前言:上篇文章介绍了.net core+Redis+IIS+nginx实现Session共享,本来打算直接说明后续填坑过程,但毕竟好多坑是用docker部署后出现的,原计划简单提一下.net core ...

  2. .Net Core Web Api实践(二).net core+Redis+IIS+nginx实现Session共享

    前言:虽说公司app后端使用的是.net core+Redis+docker+k8s部署的,但是微信公众号后端使用的是IIS部署的,虽说公众号并发量不大,但领导还是使用了负载均衡,所以在介绍docke ...

  3. .Net Core Web Api实践(四)填坑连接Redis时Timeout performing EVAL

    前言:前两篇文章.net core+Redis+IIS+nginx实现Session共享中,介绍了使用Microsoft.Extensions.Caching.Redis实现Session共享的方法, ...

  4. .net core web api + Autofac + EFCore 个人实践

    1.背景 去年时候,写过一篇<Vue2.0 + Element-UI + WebAPI实践:简易个人记账系统>,采用Asp.net Web API + Element-UI.当时主要是为了 ...

  5. ASP.NET Core Web API 最佳实践指南

    原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 介绍 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但是,你难 ...

  6. [转]ASP.NET Core Web API 最佳实践指南

    原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 转自 介绍# 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但 ...

  7. 循序渐进学.Net Core Web Api开发系列【13】:中间件(Middleware)

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如 ...

  8. 循序渐进学.Net Core Web Api开发系列【13】:中间件(Middleware)【有源码】

    原文:循序渐进学.Net Core Web Api开发系列[13]:中间件(Middleware) 系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:ht ...

  9. 加快ASP。NET Core WEB API应用程序。第3部分

    下载source from GitHub 对ASP进行深度重构和优化.NET Core WEB API应用程序代码 介绍 第1部分.创建一个测试的RESTful WEB API应用程序. 第2部分.增 ...

随机推荐

  1. PyODPS DataFrame 处理笛卡尔积的几种方式

    PyODPS 提供了 DataFrame API 来用类似 pandas 的接口进行大规模数据分析以及预处理,本文主要介绍如何使用 PyODPS 执行笛卡尔积的操作. 笛卡尔积最常出现的场景是两两之间 ...

  2. @loj - 2196@「SDOI2014」Lis

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定序列 A,序列中的每一项 Ai 有删除代价 Bi 和附加属性 ...

  3. PAN-OS 6.1 Open Source Software (OSS) Listing

    https://www.paloaltonetworks.com/documentation/oss-listings/oss-listings/pan-os-oss-listings/pan-os- ...

  4. 13 Free GIS Software Options: Map the World in Open Source

    13 Free GIS Software Options: Map the World in Open Source   A LIST OF FREE OPEN SOURCE MAPPING SOFT ...

  5. css3 word-wrap属性

    允许长单词换行到下一行: word-wrap:break-word

  6. zoj 1633 Big String

    Big String Time Limit: 2 Seconds Memory Limit: 65536 KB We will construct an infinitely long string ...

  7. java什么是跨平台性?原理是什么?

    所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行. 实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行 ...

  8. [转载] Solaris命令使用

    摘自: http://www.jb51.net/os/Solaris/18533.html   ★6. rm 删除文件 命令格式: rm [-r] filename (filename 可为档名,或档 ...

  9. C# 序列类为 xml 可以使用的特性大全

    本文告诉大家如何使用序列类,以及序列时可以用到的特性,特性的作用和一些容易被问的问题 最近我在把项目文件修改为 VisualStudio 2017 的格式,请看从以前的项目格式迁移到 VS2017 新 ...

  10. dotnet core 发布只有一个 exe 的方法

    在 dotnet core 发布的时候,会使用很多文件,这样发给小伙伴使用的时候不是很清真,本文告诉大家一个非官方的方法通过 warp 将多个文件打包为一个文件 和之前相同的方式发布一个 dotnet ...