详解在ASP.NET Core中如何编写合格的中间件

这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道。所有ASP.NET Core应用程序至少需要一个中间件来响应请求,并且您的应用程序实际上只是中间件的集合。当然MVC管道本身就是中间件,早在WebForm时代就出现过HttpModules、HttpHandler、那个时候悠然记得我通过它们来组织我的广告系统,不闲扯我们继续。

每个中间件组件都有一个带有HttpContext参数的Invoke方法。您可以使用这个参数来处理方法。

public async Task Invoke(HttpContext context)
{
 if (context.Request.Path...)
 {
  await context.Response.WriteAsync("writing text...");
 }
}

应用程序中最顶层的中间件将始终针对每个请求被调用。这是由.NET框架自动完成的。中间件可以向客户端发送响应,也可以调用下一个中间件。对于后一种选择,它当然需要访问下一个中间件组件。这就是为什么大多数中间件组件都是使用带有RequestDelegate参数的构造函数定义的。总之,RequestDelegate会自动填充,您无需在意。

中间件在Startup.cs的Configure方法中注册。Configure方法具有IApplicationBuilder参数,该参数提供了所有类型的中间件注册所需的方法,我们试着去编写一个中间件。

public class MyCustomMiddleware
 {
  private readonly RequestDelegate _next;
  public MyCustomMiddleware(RequestDelegate next)
  {
   _next = next;
  }
  public async Task Invoke(HttpContext context, IWebHostEnvironment env)
  {
   context.Response.Headers["app-name"] = env.ApplicationName+"Zaranet";
   context.Response.Headers["env-name"] = env.EnvironmentName+ "Zaranet";
   await _next(context);
  }
 }

随后我们在Startup.cs的Configure方法中通过 use 来注册自定义中间件。

public void Configure(IApplicationBuilder app, ...)
{
 app.UseMyCustomMiddleware();
}

启动程序我们发现一些正常,我们得到了我们想要的效果。

但实际上,您很少需要直接调用UseMiddleware,因为中间件作者的标准方法是编写特定于所注册中间件的扩展方法:

using MiddlerWareSolucation.MiddlerWare;
using Microsoft.AspNetCore.Builder;

namespace MiddlerWareSolucation.MiddlerWare_Extensions
{
 public static class MyCustomMiddlewareExtensions
 {
  public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder app)
  {
   app.UseMiddleware<MyCustomMiddleware>();

   return app;
  }
 }
}

随后直接调用Extensions扩展方法,效果还是一样的。

public void Configure(IApplicationBuilder app, ...)
{
 app.UseMyCustomMiddleware();
}

部分时候我们想要通过客户端请求的路径来对我们的中间件进行启动,当然 MapWhen 允许您通过指定谓词将中间件管道分成两个完全独立的分支:

app.UseMiddlewareOne();

app.MapWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
  appBuilder.UseMiddlewareTwo();
});

app.UseMiddlewareThree();

在此示例中,中间件One将始终执行,如果请求路径以“ / api”开头,则将执行中间件Two。否则,将执行中间件Three。使用这种配置,中间件2和中间件3都无法针对单个请求执行。

我想说的是最后一种情况是,您希望大多数中间件针对所有请求运行,但是您有一些条件件-特定中间件仅应针对某些请求运行。

这可以通过UseWhen轻松实现,UseWhen还使用谓词来确定中间件是否应该运行:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
 appBuilder.UseStatusCodePagesWithReExecute("/apierror/{0}");

 appBuilder.UseExceptionHandler("/apierror/500");
});

这样就可以通过选择注册方式来自己控制中间件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解在ASP.NET Core 中使用Cookie中间件

    在 http:// ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分配到HttpContext对象的User属性中.如果你想提供自己的登录方式和用户数据你可以使用Cookie中间件来实现独立的功能. 添加和配置 第一步是增加Cookie中间件到你的应用中.首先使用nuget增加Microsoft.AspNetCore.Authentication.

  • 详解ASP.NET Core 中间件之压缩、缓存

    前言 今天给大家介绍一下在 ASP.NET Core 日常开发中用的比较多的两个中间件,它们都是出自于微软的 ASP.NET 团队,他们分别是Microsoft.AspNetCore.ResponseCompression 和 Microsoft.AspNetCore.ResponseCaching , 下面让我们一起看看的功能以及如何去使用吧. Getting Started Microsoft.AspNetCore.ResponseCompression Microsoft.AspNetCo

  • Asp.Net Core 通过中间件防止图片盗链的实例

    一.原理 要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或文件.换句话说,通过referer,网站可以检测目标网页访问的来源网页,如果是资源文件,则可以跟踪到显示它的网页地址.有了referer跟踪来源就好办了,这时就可以通过技术手段来进行处理,一旦检测到来源不是本站即进行阻止或者返回指定的页面.如果想对自己的网站进行防盗链保护,则需要针对不同的情况进行区

  • 浅谈ASP.NET Core 中间件详解及项目实战

    前言 本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的Hello World. 中间件(Middleware)的作用 我们知道,任何的一个web框架都是把http请求封装成一个管道,每一次的请求都是经过管道的一系列操作,最终到达我们写的代码中.那么中间件就是在应用程序管道中的一个组件,用来拦截请求过程进行一些其他处理和响应.中间件可以有很多个,每一个中间件都可以对管道中的请求进行拦截,它可以决定是否将请求转移给下一个中间件. asp.net

  • ASP.NET Core 2.0 带初始参数的中间件问题及解决方法

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class GreetingOptions { public string GreetAt { get; set; } public string GreetTo { get; set; } } 添加一个中间件: public class GreetingMiddleware { private readon

  • 浅谈ASP.NET Core 2.0 中间件(译)

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Run(async (context) => { await context.Response.WriteAsync("Hello World! (Run)

  • 详解在ASP.NET Core中如何编写合格的中间件

    这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至少需要一个中间件来响应请求,并且您的应用程序实际上只是中间件的集合.当然MVC管道本身就是中间件,早在WebForm时代就出现过HttpModules.HttpHandler.那个时候悠然记得我通过它们来组织我的广告系统,不闲扯我们继续. 每个中间件组件都有一个带有HttpContext参数的Inv

  • 详解在ASP.NET Core中使用Angular2以及与Angular2的Token base身份认证

    Angular2是对Angular1的一次彻底的,破坏性的更新. 相对于Angular1.x,借用某果的广告语,唯一的不同,就是处处都不同. •首先,推荐的语言已经不再是Javascript,取而代之的TypeScript,(TypeScript = ES6 + 类型系统 + 类型注解), TypeScriipt的类型系统对于开发复杂的单页Web app大有帮助,同时编译成javascript后的执行效率也比大多数手写javascript要快.有兴趣的同学可以查阅官方文档:英文传送门 |中文传送

  • 详解在ASP.NET Core下使用SignalR技术

    一.前言 上次我们讲到过如何在ASP.NET Core中使用WebSocket .这次的主角是SignalR它为我们提供了简化操作WebSocket的框架. ASP .NET SignalR 是一个ASP.NET 下的类库,可以在ASP.NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的.WebSockets是HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSock

  • 详解将ASP.NET Core应用程序部署至生产环境中(CentOS7)

    将ASP.NET Core应用程序部署至生产环境中(CentOS7) 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Core SDK for CentOS7. 部署ASP.NET Core应用程序 配置Nginx 配置守护服务(Supervisor) 这段时间在使用Rabbit RPC重构公司的一套系统(微信相关),而最近相关检验(逻辑测试.压力测试)已经完成,接近部署至线上生产环境从而捣鼓了ASP.NET Core应用程序在CentOS上的部署

  • ASP.NET Core中预压缩静态文件的方法步骤

    前言 Web应用程序的优化是非常重要,因为使用更少的CPU,占用更少的带宽可以减少项目的费用. 在ASP.NET Core中我们可以很容易的启用响应压缩,但是针对预压缩文件,就需要做一些额外的功能了. 这篇博客文章展示了如何在ASP.NET Core中预压缩静态文件. 下面话不多说了,来一起看看详细的介绍吧 为什么需要预压缩文件? 虽然在从服务器请求文件时, 我们可以动态压缩文件,但这意味这Web服务器需要做更多的额外工作. 其实只有在新的应用程序部署时才会更改要压缩的文件. 越好的压缩效果需要

  • 如何在ASP.NET Core中使用Session的示例代码

    ASP.NET Core 是一个跨平台,开源的,轻量级,高性能 并且 高度模块化的web框架,Session 可以实现用户信息存储从而可以在同一个客户端的多次请求之间实现用户追踪,在 ASP.Net Core 中可以使用 Microsoft.AspNetCore.Session 中间件来启用 Session 机制. 中间件的价值在于可以在 request -> response 的过程中做一些定制化的操作,比如说:监视数据,切换路由,修改流转过程中的消息体,通常来说:中间件是以链式的方式灌入到

  • 详解ASP.Net Core 中如何借助CSRedis实现一个安全高效的分布式锁

    引言:最近回头看了看开发的.Net Core 2.1项目的复盘总结,其中在多处用到Redis实现的分布式锁,虽然在OnResultExecuting方法中做了防止死锁的处理,但在某些场景下还是会发生死锁的问题,下面我只展示部分代码: 问题: (1)这里setnx设置的值"1",我想问,你最后del的这个值一定是你自己创建的吗? (2)图中标注的步骤1和步骤2不是原子操作,会有死锁的概率吗? 大家可以思考一下先,下面让我们带着这两个问题往下看,下面介绍一下使用Redis实现分布式锁常用的

  • 详解ASP.NET Core中配置监听URLs的五种方式

    默认情况下,ASP. NET Core应用会监听一下2个Url: http://localhost:5000 https://localhost:5001 在本篇博文中,我将展示如何使用五种不同的方式改变应用监听的URLs. 在ASP.NET Core项目启动时,有多种配置监听Url的方式,在我之前的一篇博客中,已经展示了在ASP.NET Core 1.0中如何应用不同的方式配置,在ASP.NET Core 3.x中,大部分方式还是一样的. UseUrls() - 在Program.cs配置程序

  • ASP.NET Core中的配置详解

    ASP.NET Core 提供了一个灵活可扩展,基于键值的配置系统. 但是配置系统独立于ASP.NET Core是Microsoft.Extensions 类库的部分. 它可以用于任何类型的应用程序 1.以键-值对的形式读取配置 appsettings.json 文件: { "Position": { "Title": "编辑器", "Name": "Joe Smith" }, "MyKey&qu

随机推荐