ASP.Net Core MVC基础系列之中间件

上一节我们介绍了服务注册和基本的管道执行流程, 并且讲到了中间件, 这一节我们就来详细谈谈中间件这个东西

讲中间件, 其实就是讲Startup类里面的ConfigureServices 和Configure 这两个方法

在程序启动类Program 中, 我们在CreateWebHostBuilder 方法中调用了UseStartup方法, 里面用泛型注入了 Startup 类, 那程序就会自动实例化这个类, 并且去执行它里面的ConfigureServices 和Configure 这两个方法. 我们就可以做很多配置操作

首先调用的第一个方法当然就是构造函数, 这里没有没有, 我们不说, 然后就是ConfigureServices 方法. 这个方法上一节已经使用过了, 在这个方法里面, 我们可以注册一些服务或者我们叫自定义服务. 注册完服务, 我们就可以通过依奈注入的方式在其它地方使用这些服务.

然后再执行的方法就是Configure 这个方法. 我们能看到Configure 方法默认的第一个参数是IApplicationBuilder 接口, 可以理解为整个程序的根, 我们通过这个接口对象, 可以精确的配置获取启用我们的中间件, 使我们的各种中间件组合起来, 形成一个完美的Web应用程序, 去处理我们的HTTP请求并且做出对应的响应等等.

讲之前, 我们先把

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

这几行代码注释掉, 待会再用, 再去解释这个是干嘛用的, 为什么要加个if, 这里先注释掉

我们看这个代码

app.Run(async (context) =>
{
    var msg = welcome.GetWelcomMsg();
    await context.Response.WriteAsync(msg);
});

这个app.Run方法, 可以理解为我们自己写的一个中间件, 它什么都不干, 就是为响应输出一个字符串. 其实这是新建项目默认生成的.

在真实的项目中, 我们基本上不会使用app.Run这个方法去处理我们的请求, 因为我做的事情远远比输出一个字符串复杂很多.

在实际开发中, 我们通常使用的中间件都是app.Usexxxx开头的, 才能组成一个完成的Web项目, 比如 app.UseMvc / app.UseStaticFiles等等这些方法去启用系统自带的中间件获取别的第三方中间件.

我们这里启用个ASP.Net Core MVC自带的彩蛋中间件吧, 代码为:app.UseWelcomePage(); 启用默认的MVC欢迎页面. 我们F5执行.

我们能够正常看到出现了一个页面, 而不是简单的一个字符串的输出了

然后我们尝试改变一下地址栏, 随便写个什么, 可以发现, 我们随便怎么输入地址, 都是进入到欢迎页, 如图 :

到这里, 我们就可以发现, 这个"彩蛋"中间件的"优先级"还是很高的, 在ASP.Net Core MVC发现你使用了这个中间件的时候, 他就不会执行后面的东西了, 或者说不会执行后面的中间件了.

还有呢, 在我们使用中间件的时候, 或者说是在调用app.Usexxxx方法的时候, 一般来说, 这个方法都会接受一个对象参数, 这个参数可以对这个中间件进行一些配置, 下面我们尝试配置一下"彩蛋"中间件, 告诉大家中间件是怎么配置的. 代码是这样的

app.UseWelcomePage(new WelcomePageOptions
{
    Path = "/welcome"
});

都能看到, 这里是为"彩蛋"配置了一个地址(路径), 现在我们F5看看效果

会发现网页输出是个字符串, 那我们在地址后面加上 /welcome 再看看, 可以发现能正常出现"彩蛋"了, 说明这个配置是有效的.

当然我的目的不是讲这个"彩蛋"怎么使用, 而是给大家介绍中间件怎么使用, 怎么去配置中间件, 基本上所有的中间件都是这个使用方式和配置方式.

既然说到了这里, 那我们来说说 app.Use 这个方法. 这个方法怎么说呢, 就是它比较"底层", 因为app.Use里面的参数类型是RequestDelegate , 也就是当前请求对象的委托, 相对比较"底层", 可以说是当前请求管道的"原型". 我们来写一些代码试试吧.

app.Use(next =>
{
    return async context =>
    {
        if (context.Request.Path.StartsWithSegments("/first"))
        {
             await context.Response.WriteAsync("First");
        }
        else
        {
            await next(context);
        }
    };
});

我们写的代码如上, 它的意思就是: 当前地址是/first 的时候, 输出 First 这个字符串, 否则就不管, 继续往下执行, 去执行别的中间件, 我们运行看看效果. 可以发现, 默认输出的是 你好, .Net Core 2.2, 当我们把地址后面加上/first 的时候, 输出的就是First, 如图:

我们再输入地址 /welcome 的是, 可以看到"彩蛋"正常出现了, 可以看到, 我们的Use方法是正常的

在实际开发过程中, 我们很少直接使用app.Use方法去处理我们的底层请求的, 这里只是简单介绍了这个方法, 以及它能干什么.

知道app.Use是干什么的, 那就把上面的app.Use方法删掉吧, 或者注释掉, 我们下面的教程不会用的.

接下来, 我们干点坏事, 我们在 app.Run 方法里面手动报个异常出来, 代码如下:

app.Run(async (context) =>
{
    throw new Exception();
    var msg = welcome.GetWelcomMsg();
    await context.Response.WriteAsync(msg);
});

我们执行项目, 会看到出现了500错误, Chrome浏览器是这样的, 其它浏览器可能不一样

但是我们不希望这样, 我们希望我们能看到异常的详细信息, 这时候, 我们就需要启用一个异常中间件, 就是我们上面注释掉的那个 iif (env.IsDevelopment()) 的代码, 我们把它启用起来, 那么我们的Configure 方法里面代码就是这样的, 如图:

然后我们再F5运行项目, 就是这样的了, 如图:

我们的异常就很明显了, 很好排查错误

至于为什么加个if (env.IsDevelopment()), 这个代码一看就知道意思了吧, 就是当前环境是开发环境的时候, 才启用这个异常显示中间件

因为我们只希望在开发或者调试的时候, 才显示异常的详细信息, 别的环境不显示, 这样安全一些, 如果不加这个 if , 会在任何环境都会显示详细的错误信息, 这样可能会给我们的Web应用带来安全隐患.

所以, 我们再加个else , 在else里面启用一个别的中间件, 代码如下:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler();
}

这样我们不是在开发环境的时候, 发送异常就是这样的:

不至于暴露一些敏感的信息

我们发现这个启动异常页面中间件的代码写在最上面, 那我们把它移动到Configure 方法的最后面, 会怎么样呢 ? 我们试试, 代码如图:

可以看到, 我把异常页面中间件移动到最后面启用了, 我们F5运行项目, 会发现, 浏览器不出先异常页面了, 而是直接 500 错误.

可以知道, 中间件的启用顺序是有依奈关系和顺序的, 不能随便启用的, 需要在正确的位置启用对应的中间件, 如果顺序错了, 可能会导致中间件失效, 如果你在开发过程中, 启用了某个中间件, 但是它却没效果, 可以使用该思路进行排查.

到这里, 这一节就结束了, 到目前为止, 我们的Web应用功能很简单, 就是输出一个字符串和启用了一个"彩蛋".

我们还讲到了"环境", 比如上面的if (env.IsDevelopment()) 判断是不是开发环境, 那么怎么改变这个环境, 让我们在开发或者试运行和运营环境切换, 加载不同的配置和启用不同的中间件

到此这篇关于ASP.Net Core MVC基础系列之中间件的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET Core MVC/WebApi基础系列2

    >前言 好久没冒泡了,算起来估计有快半年没更新博客了,估计是我第一次停更如此之久,人总有懒惰的时候,时间越长越懒惰,但是呢,不学又不行,持续的惰性是不行dei,要不然会被时光所抛弃,技术所淘汰,好吧,进入今天的主题,本节内容,我们来讲讲.NET Core当中的模型绑定系统.模型绑定原理.自定义模型绑定.混合绑定.ApiController特性本质,可能有些园友已经看过,但是效果不太好哈,这篇是解释最为详细的一篇,建议已经学过我发布课程的童鞋也看下,本篇内容略长,请保持耐心,我只讲你们会用到的或者

  • ASP.Net Core MVC基础系列之环境设置

    上一节我们介绍了中间件的基本使用, 这一节我们讲一讲.Net Core的环境设置, 以及根据不同的环境加载不同的配置信息 PS: 由于最近一直比较忙, 一直没抽时间更新这个系列, 最近居多的博友催我, 所以继续挤挤时间更新这个系列, 感谢大家的对本系列教程的喜欢和支持. 在实际开发中, 我们的系统往往会是至少两个以上的运行环境, 最基本的就是, 开发环境和运营环境, 体系完整的公司, 还会有测试环境, 预发布环境, 和一些自定义环境等等, 这些环境使用的配置或是一些参数肯定是不一样的, 我们不可

  • ASP.Net Core MVC基础系列之项目创建

    一 : 系列教程环境介绍 1: 操作系统, Windows 10 专业版 64位 (版本号: 1809) 2: IDE使用Visual Studio 2017专业版 (版本号: 15.9.5) 3: SDK环境 .Net Core 2.2.101 4: 前端 Vue 2.X 5: 数据库 MSSQL 2017 6: 语言使用 C# 7.3 二 : .Net Core 2.2环境安装 进行.Net Core开发, 需要安装.Net Core SDK, 下载地址 下载安装完成之后在CMD里面运行do

  • ASP.NET Core MVC学习之视图组件(View Component)

    1.视图组件介绍 视图组件是 ASP.NET Core MVC 的新特性,类似于局部视图,但它更强大.视图组件不使用模型绑定,并且仅依赖于调用它时所提供的数据. 视图组件特点: 呈块状,而不是整个响应 包括在控制器和视图之间发现的相同的关注点和可测试性优点 可以拥有参数和业务逻辑 通常从布局页面调用 视图组件可以用在任何需要重复逻辑且对局部视图来说过于复杂的情况,例如: 动态导航菜单 标签云(需要查询数据库) 登录面板 购物车 最近发表的文章 典型博客上的侧边栏内容 将在每个页面上呈现的登录面板

  • asp.net mvc core管道及拦截器的理解

    今天来看一下asp.net core的执行管道.先看下官方说明: 从上图可以抛光,asp.net core的执行顺序是,当收到一个请求后,request请求会先经过已注册的中间件,然后会进入到mvc的拦截器管道: 进入mvc管道后,根据以上顺序执行过滤校正. OK,根据以上说明下面我们新建一个MVC的演示,将执行方式切换为控台运行: // This method gets called by the runtime. Use this method to add services to the

  • ASP.NET Core MVC/WebApi基础系列1

    >前言 最近发表的EF Core貌似有点多,可别误以为我只专攻EF Core哦,私下有时间也是一直在看ASP.NET Core的内容,所以后续会穿插讲EF Core和ASP.NET Core,别认为你会用ASP.NET Core就自认为你很了解ASP.NET Core,虽说是基础系列但也是也有你不知道的ASP.NET Core. UseStaticFiles.UseDefaultFiles.UseDirectoryBrowser.UseFileServer 当我们创建默认.NET Core We

  • ASP.Net Core MVC基础系列之获取配置信息

    这一节, 我们来讲解.Net Core 是怎么获取配置信息的. .Net Core配置信息来源主要有以下几种 1.appsettings.json文件 2. User Secrets 3. 环境变量 4. 命令行参数 5. 自定义XML等等 在我们上一节新建的项目中, 已经默认有appsettings.json文件了, 并且appsettings.json默认会加载到项目中来, 至于为什么会默认加载, 我们可以通过源码进行分析, VS2017反编译不好用, F12看不到完整的代码, 这里我使用I

  • ASP.NET Core MVC基础学习之局部视图(Partial Views)

    1.什么是局部视图 局部视图是在其他视图中呈现的视图.通过执行局部视图生成的HTML输出呈现在调用视图中.与视图一样,局部视图使用 .cshtml 文件扩展名.当希望在不同视图之间共享网页的可重用部分时,就可以使用局部视图. 2.什么时候使用局部视图 局部视图是将大视图分成小组件的有效方法.通用的布局元素应在 _Layout.cshtml 中指定,非布局可重用内容可以封装成局部视图. 如果一个由几个逻辑部分组成的复杂页面,那么将每个逻辑部分作为局部视图是很有用.布局视图与普通视图之间没有语义差别

  • ASP.NET Core MVC学习教程之路由(Routing)

    前言 ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序的URL命名形式,使得它在搜索引擎优化(SEO)和链接生成中运行良好,而不用关心Web服务器上的文件是怎么组织的.我们可以方便的使用路由模板语法定义路由,路由模板语法支持路由值约束,默认值和可选值. 基于约束的路由允许全局定义应用支持的URL格式,以及这些格式是怎样各自在给定的控制器中映射到指定的操作方法(Action

  • ASP.Net Core MVC基础系列之服务注册和管道

    想必大家都知道ASP.Net Core MVC默认自带了DI容器的, 我们可以很方便的进行使用, 来方便管理对象和生命周期, 那么这一节我就会详细讲解服务注册, 顺便简单讲解一下管道, 让大家知道了基本的MVC运行流程. 回顾一下上一节的内容, 我们从配置文件中获取了输出的字符, 也介绍各个配置的 "优先级" (其实是配置覆盖), 那么我们这一节以服务的方式输出这个字符串, 然后用过DI进行注册服务, 快速了解服务注册. DI容器呢, 依赖接口, 所以我们先新建一个接口, 就叫 IWe

随机推荐