ASP.NET Core中间件用法与官方常用中间件介绍

目录
  • 一、什么是中间件
    • 中间件和过滤器的区别
  • 二、中间件常用方法
    • 1、Run方法
    • 2、Use方法
    • 3、Map方法
    • 4、Mapwhen方法
  • 三、自定义中间件
  • 四、官方常用中间件
    • 1、异常处理中间件
    • 2、HTTPS重定向中间件
    • 3、静态文件中间件
    • 4、Cookie中间件
    • 5、路由中间件
    • 6、身份认证中间件
    • 7、授权中间件
    • 8、会话中间件
    • 9、终结点路由中间件

一、什么是中间件

我们都知道,任何的一个web框架都是把http请求封装成一个管道,每一次的请求都是经过管道的一系列操作,最终才会到达我们写的代码中。而中间件就是用于组成应用程序管道来处理请求和响应的组件。管道内的每一个组件都可以选择是否将请求转交给下一个组件,并在管道中调用下一个组件之前和之后执行某些操作。请求委托被用来建立请求管道,请求委托处理每一个HTTP请求。

中间件可以认为有两个基本的职责:

  • 选择是否将请求传递给管道中的下一个中间件。
  • 可以在管道中的下一个中间件前后执行一些工作。

请求委托通过使用IApplicationBuilder类型的Run、Map以及Use扩展方法来配置,并在Startup类中传给Configure方法。每个单独的请求委托都可以被指定为一个内嵌匿名方法,或其定义在一个可重用的类中。这些可以重用的类被称作“中间件”或“中间件组件”。每个位于请求管道内的中间件组件负责调用管道中下一个组件,或适时短路调用链。中间件是一个典型的AOP应用。

ASP.NET Core请求管道由一系列的请求委托所构成,它们一个接着一个的被调用,看下面一张微软官方的中间件请求管道图(图中执行线程按黑色箭头的顺序执行):

中间件短路:每一个委托在下一个委托之前和之后都有机会执行操作。任何委托都能选择停止传递到下一个委托,而是结束请求并开始响应,这就是请求管道的短路,这是一种有意义的设计,因为它可以避免一些不必要的工作。比如说,一个授权(authorization)中间件只有在通过身份验证之后才能调用下一个委托,否则它就会被短路,并返回“Not Authorized”的响应。异常处理委托需要在管道的早期被调用,这样它们就能够捕捉到发生在管道内更深层次出现的异常了。短路可以用下面这张图来表示:

在上图中,我们可以把中间件1认为是身份认证的中间件,HTTP请求发送过来,首先经过身份认证中间件,如果身份认证失败,那么就直接给出响应并返回,不会再把请求传递给下面的中间件2和中间件3.

中间件的执行跟调用的顺序有关,然后在响应时则以相反的顺序返回。

请求在每一步都可能被短路,所以我们要以正确的顺序添加中间件,如异常处理中间件,我们要添加在最开始的地方,这样就能第一时间捕获异常,以及后续中间可能发生的异常,然后最终做处理返回。

我们来看看Configure方法里面提供了哪些中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // 异常中间件
        app.UseDeveloperExceptionPage();
    }

    // 路由中间件
    app.UseRouting();
    // 授权中间件
    app.UseAuthorization();
    // 终结点中间件
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

中间件和过滤器的区别

中间件和过滤器都是一种AOP的思想,他们的功能类似,那么他们有什么区别呢?

过滤器更加贴合业务,它关注于应用程序本身,关注的是如何实现业务,比如对输出结果进行格式化,对请求的ViewModel进行数据校验,这时就肯定要使用过滤器了。过滤器是MVC的一部分,它可以拦截到你Action上下文的一些信息,而中间件是没有这个能力的。可以认为过滤器是附加性的一种功能,它只是中间件附带表现出来的特征。中间件是管道模型里重要的组成部分,不可或缺,而过滤器可以没有。

二、中间件常用方法

中间件中定义了Run、Use、Map、MapWhen几种方法,我们下面一一讲解这几种方法。

1、Run方法

我们先来看到Run()方法的定义:

中定义中可以看出:Run()方法中只有一个RequestDelegate委托类型的参数,没有Next参数,所以Run()方法也叫终端中间件,不会将请求传递给下一个中间件,也就是发生了“短路”。看下面的代码:

// Run方法向应用程序的请求管道中添加一个RequestDelegate委托
// 放在管道最后面,终端中间件
app.Run(handler: async context =>
{
    await context.Response.WriteAsync(text: "Hello World1\r\n");
});
app.Run(handler: async context =>
{
    await context.Response.WriteAsync(text: "Hello World2\r\n");
});

程序运行结果:

可以看到:只输出了中间件1的信息,没有输出中间件2的信息,说明发生了短路。

注意:Run()方法被称为终端中间件,要放在所有中间件的最后面,否则在Run()方法后面的中间件将不会被执行。

2、Use方法

我们先来看看Use()方法的定义:

可以看出:Use方法的参数是一个Func委托,输入参数是一个RequestDelegate类型的委托,返回参数也是一个RequestDelegate类型的委托,这里表示调用下一个中间件,我们在来看看RequestDelegate委托的定义:

可以看出:RequestDelegate是一个委托,有一个HttpContext类型的参数,HttPContext表示Http请求上下文,可以获取请求信息,返回值是Task类型,明白了Use()方法的参数以后,我们写一个自定义的Use()方法:

// 向应用程序的请求管道中添加一个Func委托,这个委托其实就是所谓的中间件。
// context参数是HttpContext,表示HTTP请求的上下文对象
// next参数表示管道中的下一个中间件委托,如果不调用next,则会使管道短路
// 用Use可以将多个中间件链接在一起
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync(text: "hello Use1\r\n");
    // 调用下一个委托
    await next();
});
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync(text: "hello Use2\r\n");
    // 调用下一个委托
    await next();
});

程序运行结果:

我们在上面说过,可以在调用中间件之前和之后做一些工作,看下面的代码:

// 向应用程序的请求管道中添加一个Func委托,这个委托其实就是所谓的中间件。
// context参数是HttpContext,表示HTTP请求的上下文对象
// next参数表示管道中的下一个中间件委托,如果不调用next,则会使管道短路
// 用Use可以将多个中间件链接在一起
app.Use(async (context, next) =>
{
    // 解决中文乱码问题
    context.Response.ContentType = "text/plain; charset=utf-8";
    await context.Response.WriteAsync(text: "中间件1:传入请求\r\n");
    // 调用下一个委托
    await next();
    await context.Response.WriteAsync(text: "中间件1:传出响应\r\n");
});
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync(text: "中间件2:传入请求\r\n");
    // 调用下一个委托
    await next();
    await context.Response.WriteAsync(text: "中间件2:传出响应\r\n");
});
app.Run(handler:async context =>
{
    await context.Response.WriteAsync(text: "中间件3:处理请求并生成响应\r\n");
});

程序运行结果:

我们可以总结上面代码的执行顺序:

  • 请求先到达中间件1,然后输出(中间件1:传入请求)
  • 然后中间件1调用next()。next()会调用管道中的中间件2。
  • 中间件2输出(中间件2:传入请求)。
  • 然后中间件2会调用next()。next()在调用管道中的中间件3。
  • 中间件3处理请求并生成响应,不在调用下一个中间件,所以我们看到输出(中间件3:处理请求并生成响应)。
  • 这时管理开始发生逆转。
  • 此时控制器将交回到中间件2,并将中间件3生成的响应传递给它。中间件2输出(中间件2:传出响应)。
  • 最后,中间件2在将控制权交给中间件1。
  • 中间件1最后输出(中间件1:传出响应),这就是我们最后看的的结果。

我们知道:Use()方法中有两个参数,next参数表示调用管道中的下一个中间件,如果不调用next,那么也会使管道发生短路,相当于Run()方法,看下面的代码:

// 向应用程序的请求管道中添加一个Func委托,这个委托其实就是所谓的中间件。
// context参数是HttpContext,表示HTTP请求的上下文对象
// next参数表示管道中的下一个中间件委托,如果不调用next,则会使管道短路
// 用Use可以将多个中间件链接在一起
app.Use(async (context, next) =>
{
    // 解决中文乱码问题
    context.Response.ContentType = "text/plain; charset=utf-8";
    await context.Response.WriteAsync(text: "中间件1:传入请求\r\n");
    // 调用下一个委托
    await next();
    await context.Response.WriteAsync(text: "中间件1:传出响应\r\n");
});
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync(text: "中间件2:传入请求\r\n");
    // 调用下一个委托
    await next();
    await context.Response.WriteAsync(text: "中间件2:传出响应\r\n");
});
//app.Run(handler:async context =>
//{
//    await context.Response.WriteAsync(text: "中间件3:处理请求并生成响应\r\n");
//});
// Use方法也可以不调用next,表示发生短路
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync(text: "中间件3:处理请求并生成响应\r\n");
});

程序运行结果:

可以看出:如果使用Use()方法,不调用next,实现的效果跟使用Run()方法一样,都会使管道发生短路。

3、Map方法

Map作为惯例,将管道分流。Map根据给定请求路径匹配将请求管道分流。如果请求路径以指定路径开始,则执行分支。看一下Map()方法的定义:

可以看到Map方法有两个参数:第一个参数是匹配规则,第二个参数是Action泛型委托,泛型委托参数是IApplicationBuilder类型,和Configure方法的第一个参数类型相同。这就表示可以把实现了Action泛型委托的方法添加到中间件管道中执行。

我们首先定义一个方法,该方法的参数是IApplicationBuilder类型:

/// <summary>
/// 自定义方法
/// </summary>
/// <param name="app">IApplicationBuilder</param>
private void HandleMap1(IApplicationBuilder app)
{
    app.Run(handler: async context =>
    {
        await context.Response.WriteAsync(text: "Hello Map1");
    });
}

/// <summary>
/// 自定义方法
/// </summary>
/// <param name="app">IApplicationBuilder</param>
private void HandleMap2(IApplicationBuilder app)
{
    app.Run(handler: async context =>
    {
        await context.Response.WriteAsync(text: "Hello Map2");
    });
}

然后看一下使用Map方法的代码:

// Map可以根据匹配的URL来选择执行,简单来说就是根据URL进行分支选择执行
// 有点类似于MVC中的路由
// 匹配的URL:http://localhost:5000/Map1
app.Map(pathMatch: "/Map1", configuration: HandleMap1);
// 匹配的URL:http://localhost:5000/Map2
app.Map(pathMatch: "/Map2", configuration: HandleMap2);

运行程序,然后在浏览器地址栏里面输入:http://localhost:5000/Map1,输出结果:

在地址栏里面在输入:http://localhost:5000/Map2,输出结果:

Map还支持嵌套,看下面的代码:

// 嵌套Map
app.Map(pathMatch: "/Map1", configuration: App1 =>
{
    //
    App1.Map("/Map2",action=>
    {
        action.Run(async context =>
        {
            await context.Response.WriteAsync("This is /Map1/Map2");
        });
    });
    App1.Run(async context =>
    {
        await context.Response.WriteAsync("This is no-map");
    });
});

访问http://localhost:5000/Map1/123输出结果:

访问http://localhost:5000/Map1输出结果:

访问http://localhost:5000/Map1/Map2输出结果:

Map也可以同时匹配多个段,看下面的代码:

运行程序,输出结果:

访问http://localhost:5000/Map1/Map2输出结果:

4、Mapwhen方法

MapWhen是基于给定的谓词分支请求管道。任何使Func<HttpContext,bool>返回true的谓词的请求都被映射到新的管道分支。

我们先来看看Mapwhen方法的定义:

可以看出:MapWhen方法有两个参数:第一个参数是Func类型的委托,输入参数是HttpContext,输出参数是bool类型。第二个参数是Action委托,参数是IApplicationBuilder类型,表示也可以把实现Action委托的方法添加到中间件管道中执行。

看下面的例子,如果url中包括name查询参数,则执行HandleName方法,如果包含age查询参数,则执行HandleAge方法,否则执行Run()方法。

HandleName和HandleAge方法定义如下:

private void HandleName(IApplicationBuilder app)
{
    app.Run(handler: async context =>
    {
        await context.Response.WriteAsync(text: $"This name is: {context.Request.Query["name"]}");
    });
}

private void HandleAge(IApplicationBuilder app)
{
    app.Run(handler: async context =>
    {
        await context.Response.WriteAsync(text: $"This age is: {context.Request.Query["age"]}");
    });
}

对应的MapWhen方法定义如下:

// 如果访问的url参数中包含name,则执行HandleName
app.MapWhen(
// Func委托,输入参数是HttpContext,返回bool值
predicate: context =>
{
    // 判断url参数中是否包含name
    return context.Request.Query.ContainsKey("name");
}, configuration: HandleName);

// 如果访问的url参数中包含name,则执行HandleAge
app.MapWhen(
// Func委托,输入参数是HttpContext,返回bool值
predicate: context =>
{
    // 判断url参数中是否包含age
    return context.Request.Query.ContainsKey("age");
}, configuration: HandleAge);

app.Run(async context =>
{
    await context.Response.WriteAsync("There is non-Map delegate \r\n");
});

运行程序,输出结果:

在url里面添加name查询参数输出结果:

在url里面添加age查询参数输出结果:

三、自定义中间件

在上面的例子中,我们都是使用的官方中间件自动的方法,其实我们也可以自己编写一个中间件。

中间件遵循显示依赖原则,并在其构造函数中暴露所有依赖项。中间件能够利用UseMiddleware<T>扩展方法的优势,直接通过它们的构造函数注入服务。依赖注入服务是自动完成填充的。

ASP.NET Core约定中间件类必须包括以下内容:

  • 具有类型为RequestDelegate参数的公共构造函数。
  • 必须有名为Invoke或InvokeAsync的公共方法,此方法必须满足两个条件:方法返回类型是Task、方法的第一个参数必须是HttpContext类型。

我们自定义一个记录IP的中间件,新建一个类RequestIPMiddleware,代码如下:

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MiddlewareDemo.Middleware
{
    /// <summary>
    /// 记录IP地址的中间件
    /// </summary>
    public class RequestIPMiddleware
    {
        // 私有字段
        private readonly RequestDelegate _next;

        /// <summary>
        /// 公共构造函数,参数是RequestDelegate类型
        /// 通过构造函数进行注入,依赖注入服务会自动完成注入
        /// </summary>
        /// <param name="next"></param>
        public RequestIPMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        /// <summary>
        /// Invoke方法
        /// 返回值是Task,参数类型是HttpContext
        /// </summary>
        /// <param name="context">Http上下文</param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            await context.Response.WriteAsync($"User IP:{context.Connection.RemoteIpAddress.ToString()}\r\n");
            // 调用管道中的下一个委托
            await _next.Invoke(context);
        }
    }
}

然后创建一个扩展方法,对IApplicationBuilder进行扩展:

using Microsoft.AspNetCore.Builder;

namespace MiddlewareDemo.Middleware
{
    public static class RequestIPExtensions
    {
        /// <summary>
        /// 扩展方法,对IApplicationBuilder进行扩展
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseRequestIP(this IApplicationBuilder builder)
        {
            // UseMiddleware<T>
            return builder.UseMiddleware<RequestIPMiddleware>();
        }
    }
}

最后在Startup类的Configure方法中使用自定义中间件:

// 使用自定义中间件
app.UseRequestIP();

运行程序,查看结果:

这样就完成了一个自定义中间件。

四、官方常用中间件

1、异常处理中间件

当应用程序在开发环境中运行时,开发人员异常页中间件( UseDeveloperExceptionPage )报告应用程序运行时的错误。

当应用程序在生产环境中运行时,异常处理中间件( UseExceptionHandler )捕获下面中间件中引发的异常。

2、HTTPS重定向中间件

HTTPS重定向中间件( UseHttpsRedirection )会将HTTP请求重定向到HTTPS。

3、静态文件中间件

静态文件中间件( UseStaticFiles )返回静态文件,并简化进一步请求处理。

4、Cookie中间件

Cookie策略中间件( UseCookiePolicy )使应用符合欧盟一般数据保护条例的规定。

5、路由中间件

路由中间件( UseRouting )用于路由的请求。

6、身份认证中间件

身份认证中间件( UseAuthentication )尝试对用户进行身份验证,验证通过之后才会允许用户访问安全资源。

7、授权中间件

授权中间件( UseAuthorization )用于授权验证通过的用户可以访问哪些资源。

8、会话中间件

会话中间件( UseSession )建立和维护会话状态。如果应用程序使用会话状态,请在Cookie策略中间件之后和MVC中间件之前调用会话中间件。

9、终结点路由中间件

终结点路由中间件( UseEndpoints )用于将 Razor Pages 终结点添加到请求管道。

更多中间件组件可以到aspnet 的GitHub仓库中查看:https://github.com/aspnet

示例代码GitHub地址:https://github.com/jxl1024/Middleware

到此这篇关于ASP.NET Core中间件用法与官方常用中间件的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

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

    上一节我们介绍了服务注册和基本的管道执行流程, 并且讲到了中间件, 这一节我们就来详细谈谈中间件这个东西 讲中间件, 其实就是讲Startup类里面的ConfigureServices 和Configure 这两个方法 在程序启动类Program 中, 我们在CreateWebHostBuilder 方法中调用了UseStartup方法, 里面用泛型注入了 Startup 类, 那程序就会自动实例化这个类, 并且去执行它里面的ConfigureServices 和Configure 这两个方法.

  • ASP.NET Core中间件初始化的实现

    前言 在日常使用ASP.NET Core开发的过程中我们多多少少会设计到使用中间件的场景,ASP.NET Core默认也为我们内置了许多的中间件,甚至有时候我们需要自定义中间件来帮我们处理一些请求管道过程中的处理.接下来,我们将围绕着以下几个问题来简单探究一下,关于ASP.NET Core中间件是如何初始化的 首先,使用UseMiddleware注册自定义中间件和直接Use的方式有何不同 其次,使用基于约定的方式定义中间件和使用实现IMiddleware接口的方式定义中间件有何不同 再次,使用基

  • 理解ASP.NET Core 中间件(Middleware)

    目录 中间件 中间件管道 Run Use UseWhen Map MapWhen Run & Use & UseWhen & Map & Map 编写中间件并激活 基于约定的中间件 基于工厂的中间件 基于约定的中间件 VS 基于工厂的中间件 中间件 先借用微软官方文档的一张图: 可以看到,中间件实际上是一种配置在HTTP请求管道中,用来处理请求和响应的组件.它可以: 决定是否将请求传递到管道中的下一个中间件 可以在管道中的下一个中间件处理之前和之后进行操作 此外,中间件的注

  • ASP.NET Core基础之异常中间件

    了解异常中间件 首先,使用ASP.NET模板创建一个核心应用程序.默认情况下,ASP.NET核心应用程序只是返回应用程序未处理的异常的状态代码.如下所示,我们引发异常. 运行应用程序时,将得到以下输出. 如上图所示,它为您提供的状态代码为 500,这意味着内部服务器错误.但是,作为开发人员,在开发应用程序时,您应该知道有关页面上异常的详细信息,以便可以采取必要的操作来修复错误. 如何使用异常中间件? 如果希望应用程序显示显示有关未处理异常的详细信息的页面,则需要在请求处理管道中配置开发人员异常页

  • ASP.NET Core 中间件的使用之全局异常处理机制

    目录 1.创建项目 2.创建全局异常过滤器 3.依赖注入全局异常处理机制 4.测试全局异常处理机制 前言: 我们经常听到"秒修复秒上线",觉得很厉害的样子. 其实不然,这只是一个调侃而已,出现问题的方式很多(逻辑漏洞.代码异常.操作方式不正确等). 我们今天来说代码异常问题怎么快速定位,减少不必要的时间浪费. 这就是今天的主题"添加全局异常处理机制"捕捉异常存储到数据库(mongodb.SqlServer.MySQL等). PS:输出txt的话不怎么友好,不是所有人

  • ASP.NET Core基础之中间件

    什么是ASP.NET Core Middleware? ASP.NET Core中间件组件是被组装到应用程序管道中以处理HTTP请求和响应的软件组件(从技术上来说,组件只是C#类). ASP.NET Core应用程序中的每个中间件组件都执行以下任务. 选择是否将 HTTP 请求传递给管道中的下一个组件.这可以通过在中间件中调用下一个 next() 方法实现. 可以在管道中的下一个组件之前和之后执行工作. 在ASP.NET Core中,已经有很多内置的中间件组件可供使用,您可以直接使用它们. 如果

  • 详解ASP.NET Core中间件Middleware

    本文为官方文档译文,官方文档现已非机器翻译 https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-2.1 什么是中间件(Middleware)? 中间件是组装到应用程序管道中以处理请求和响应的软件. 每个组件: 选择是否将请求传递给管道中的下一个组件. 可以在调用管道中的下一个组件之前和之后执行工作. 请求委托(Request delegates)用于构建请求管道,处理每个HTT

  • ASP.NET Core的中间件与管道介绍

    今天来讨论一个ASP.NET Core 很重要概念管道和中间件,在ASP.NET Core中,针对HTTP请求采用pipeline也就是通常说的管道方式来处理,而管道容器内可以挂载很多中间件(处理逻辑)“串联”来处理HTTP请求,每一个中间件都有权决定是否需要执行下一个中间件,或者直接做出响应.这样的机制使得HTTP请求能够很好的被层层处理和控制,并且层次清晰处理起来甚是方便. 示意图如下: 为了再次说明管道和中间件的概念,举一个官方给出的权限验证的例子,中间件A,B分别按顺序挂载在管道容器中,

  • ASP.NET Core中间件用法与官方常用中间件介绍

    目录 一.什么是中间件 中间件和过滤器的区别 二.中间件常用方法 1.Run方法 2.Use方法 3.Map方法 4.Mapwhen方法 三.自定义中间件 四.官方常用中间件 1.异常处理中间件 2.HTTPS重定向中间件 3.静态文件中间件 4.Cookie中间件 5.路由中间件 6.身份认证中间件 7.授权中间件 8.会话中间件 9.终结点路由中间件 一.什么是中间件 我们都知道,任何的一个web框架都是把http请求封装成一个管道,每一次的请求都是经过管道的一系列操作,最终才会到达我们写的

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

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

  • ASP.NET Core Web资源打包与压缩技术介绍

    概述 在ASP.Net中可以使用打包与压缩这两种技术来提高Web应用程序页面加载的性能.通过减少从服务器请求的次数和减少资源文件的体积来提高加载性能. 打包是一地将多个文件(CSS,JavaScript等资源文件)合并或打包到单个文件.文件合并可减少了 Web 资源文件从服务器的所需请求数,这样也可提高页面载入的性能. 压缩是将各种不同的代码进行优化,以减少请求资源文件的体积.压缩的常见方法删除不必要的空格和注释,并将变量名缩减为一个字符. 例如下面JavaScript函数: AddAltToI

  • ASP.NET Core应用错误处理之DeveloperExceptionPageMiddleware中间件呈现“开发者异常页面”

    前言 在<ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式>中,我们通过几个简单的实例演示了如何呈现一个错误页面,这些错误页面的呈现分别由三个对应的中间件来完成,接下来我们将对这三个中间件进行详细介绍.在开发环境呈现的异常页面是通过一个类型为DeveloperExceptionPageMiddleware中间件实现的. public class DeveloperExceptionPageMiddleware { public DeveloperExceptionPageM

  • ASP.NET Core使用GraphQL第二章之中间件

    前言 在开始本文之前,对GraphQL不熟悉的朋友们,可以看下下面这篇文章: 前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 看完上面的文章,下面话不多说了,来一起看看详细的介绍吧 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app.Run(async (context) => { var result = await new DocumentExecuter() .ExecuteAsync(d

  • ASP.NET Core应用错误处理之StatusCodePagesMiddleware中间件针对响应码呈现错误页面

    前言 StatusCodePagesMiddleware中间件与ExceptionHandlerMiddleware中间件比较类似,它们都是在后续请求处理过程中"出错"的情况下利用一个错误处理器来完成最终的请求处理与响应的任务.它们之间的差异在于对"错误"的界定上,对于ExceptionHandlerMiddleware中间件来说,它所谓的错误就是抛出异常,但是对于StatusCodePagesMiddleware中间件来说,则将介于400~599之间的响应状态码视

  • ASP.NET Core中Razor页面与MVC区别介绍

    作为.NET Core 2.0发行版的一部分,还有一些ASP.NET的更新.其中之一是添加了一个新的Web框架来创建“页面”,而不需要复杂的ASP.NET MVC.新的Razor页面是一个比较简单的MVC框架版本,在某些方面是老的“.aspx” WebForms的演变. 在本文中,我们将介绍使用ASP.NET Razor页面和MVC的一些细节. Razor页面基础知识 ASP.NET MVVM vs MVC Razor页面的优点和缺点 使用Handlers实现多个GET.POST Action方

  • ASP.NET Core应用错误处理之ExceptionHandlerMiddleware中间件呈现“定制化错误页面”

    前言 DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMiddleware中间件则是面向最终用户的,我们可以利用它来显示一个友好的定制化的错误页面.按照惯例,我们还是先来看看ExceptionHandlerMiddleware的类型定义. public class ExceptionHandlerMiddleware { public Excepti

  • ASP.NET Core中Cookie验证身份用法详解

    目录 添加配置 ASP.NETCore1.x ASP.NETCore2.x 创建身份认证Cookie ASP.NETCore1.x ASP.NETCore2.x Signingout(登出) ASP.NETCore1.x ASP.NETCore2.x 服务端变化反馈 ASP.NETCore1.x ASP.NETCore2.x Cookie设置选项 ASP.NETCore1.x ASP.NETCore2.x 持久Cookie ASP.NETCore1.x ASP.NETCore2.x 绝对到期时间

随机推荐