宿主

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

CreateDefaultBuilder 创建 IHostBuilder 对象时所包含的主要默认选项包括:

  • 配置 Kestrel 服务器作为默认的 Web 服务器来负责处理 Web 的请求与响应
  • 使用当前目录作为应用程序的内容目录(ContentRoot),该目录决定了 ASP.NET Core 查找内容文件(如 MVC 视图等)的位置
  • 从以 ASPNETCORE_ 开头的环境变量(如 ASPNETCORE_ENVIRONMENT)中以及命令行参数中加载配置项
  • 从 appsettings.json、appsettings.{Environment}.json、用户机密(仅开发环境)、环境变量和命令行参数等位置加载应用设置
  • 配置日志功能,默认添加控制台输出和调式输出
  • 如果应用程序被托管在 IIS 中,启动 IIS 集成,它会配置应用程序的主机地址和端口,并允许捕获启动错误等

启动

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }

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

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
  • ConfigureServices 用于向 ASP.NET Core 的依赖注入容器添加服务
  • Configure 用于添加中间件,配置请求管道

这两个方法都会在运行时被调用,且在应用程序的整个生命周期内,只执行一次。其中 ConfigureServices 方法是可选的,而 Configure 方法则是必须的。在程序启动时,它会执行 ConfigureServices 方法(如果有),将指定的服务放入应用程序的依赖注入容器中,然后再执行 Configure 方法,向请求管道中添加中间件。

中间件

所谓中间件,就是处理 HTTP 请求和响应的组件,它本质上是一段用来处理请求与响应的代码。多个中间件之间的链式关系使之形成了管道(Pipeline)或者请求管道。管道意味着请求将从一端进入,并按照一定的顺序由每一个中间件处理,最后由另一端出来。

添加中间件:

Run & Use

// Use 方法在处理完成后还会将请求传入下一个中间件,并由它继续处理
app.Use(async (context, next) =>
{
    Console.WriteLine("中间件 A:开始");
    await next();// 下一个中间件
    Console.WriteLine("中间件 A:结束");
});

app.Run(async (context) =>
{
    Console.WriteLine("中间件 B");
    await context.Response.WriteAsync("Hello, world");
});

启动程序,输出如下:

中间件 A:开始
中间件 B
中间件 A:结束

Map

app.Use(async (context, next) =>
{
    Console.WriteLine("中间件 A:开始");
    await next();// 下一个中间件
    Console.WriteLine("中间件 A:结束");
});

// 根据是否配置指定的请求路径来决定是否在一个新分支上继续执行后续的中间件
// 并且在新分支上执行完后,不再回到原来的管道上
app.Map(new PathString("/maptest"),
    a => a.Use(async (context, next) =>
{
    Console.WriteLine("中间件 B:开始");
    await next(); // 下一个中间件
    Console.WriteLine("中间件 B:结束");
}));

app.Run(async context =>
{
    Console.WriteLine("中间件 C");
    await context.Response.WriteAsync("Hello, world");
});

访问 https://localhost:5001/maptest

中间件 A:开始
中间件 B:开始
中间件 B:结束
中间件 A:结束

UseWhen

// Use 方法在处理完成后还会将请求传入下一个中间件,并由它继续处理
app.Use(async (context, next) =>
{
    Console.WriteLine("中间件 A:开始");
    await next();// 下一个中间件
    Console.WriteLine("中间件 A:结束");
});

// 所有添加的中间件都会执行
app.UseWhen(context => context.Request.Path.Value == "/maptest",
    a => a.Use(async (context, next) =>
{
    Console.WriteLine("中间件 B:开始");
    await next(); // 下一个中间件
    Console.WriteLine("中间件 B:结束");
}));

app.Run(async context =>
{
    Console.WriteLine("中间件 C");
    await context.Response.WriteAsync("Hello, world");
});

访问 https://localhost:5001/maptest

中间件 A:开始
中间件 B:开始
中间件 C
中间件 B:结束
中间件 A:结束

自定义中间件

public class HttpMethodCheckMiddleware
{
    // 在管道中的下一个中间件
    private readonly RequestDelegate _next;

    /// <summary>
    /// 构造函数中可以得到下一个中间件,并且还可以注入需要的服务,比如 IHostEnvironment
    /// </summary>
    /// <param name="requestDelegate"></param>
    /// <param name="environment"></param>
    public HttpMethodCheckMiddleware(RequestDelegate requestDelegate, IHostEnvironment environment)
    {
        this._next = requestDelegate;
    }

    /// <summary>
    /// 对 HTTP 请求方法进行判断,如果符合条件则继续执行下一个中间件
    /// 否则返回 400 Bad Request 错误,并在响应中添加自定义消息头用于说明错误原因
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task Invoke(HttpContext context)
    {
        var requestMethod = context.Request.Method.ToUpper();
        if (requestMethod == HttpMethods.Get || requestMethod == HttpMethods.Head)
        {
            return _next(context);
        }
        else
        {
            context.Response.StatusCode = 400;
            context.Response.Headers.Add("X-AllowHTTPWeb", new[] {"GET,HEAD"});
            context.Response.WriteAsync("只支持 GET、HEAD 方法");
            return Task.CompletedTask;
        }
    }
}

添加自定义中间件

app.UseMiddleware<HttpMethodCheckMiddleware>();

创建扩展方法

public static class CustomMiddlewareExtensions
{
    public static IApplicationBuilder UseHttpMethodCheckMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpMethodCheckMiddleware>();
    }
}

调用扩展方法添加中间件

app.UseHttpMethodCheckMiddleware();

参考资料

《ASP.ENT Core 与 RESTful API 开发实战》

如果阅读文章后有所收获,希望您可以点一个推荐,感觉不尽!!!

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

ASP.NET Core 核心特性--宿主、启动、中间件的更多相关文章

  1. Asp.Net Core 第06局:中间件

    总目录 前言 本文介绍Asp.Net Core 中间件. 环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 开局 第一手:中间件概述     1.中间件:添加到应用 ...

  2. ASP.NET Core管道详解[6]: ASP.NET Core应用是如何启动的?[下篇]

    要承载一个ASP.NET Core应用,只需要将GenericWebHostService服务注册到承载系统中即可.但GenericWebHostService服务具有针对其他一系列服务的依赖,所以在 ...

  3. asp.net core 核心对象解析

    首先声明这篇文章的所有内容均来自https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html ----感谢大内老A(artec ...

  4. Asp.Net Core 3.1 的启动过程5

    前言 本文主要讲的是Asp.Net Core的启动过程,帮助大家掌握应用程序的关键配置点. 1.创建项目 1.1.用Visual Studio 2019 创建WebApi项目. 这里面可以看到有两个关 ...

  5. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  6. [转]ASP.NET Core 中的那些认证中间件及一些重要知识点

    本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...

  7. asp.net core mvc剖析:启动流程

    asp.net core mvc是微软开源的跨平台的mvc框架,首先它跟原有的MVC相比,最大的不同就是跨平台,然后又增加了一些非常实用的新功能,比如taghelper,viewcomponent,D ...

  8. asp.net core 教程(六)-中间件

    Asp.Net Core-中间件 在这一章,我们将了解如何设置中间件.中间件技术在 ASP.NET Core中控制我们的应用程序如何响应 HTTP 请求.它还可以控制应用程序的异常错误,这是一个在如何 ...

  9. Asp .Net core 2 学习笔记(2) —— 中间件

    这个系列的初衷是便于自己总结与回顾,把笔记本上面的东西转移到这里,态度不由得谨慎许多,下面是我参考的资源: ASP.NET Core 中文文档目录 官方文档 记在这里的东西我会不断的完善丰满,对于文章 ...

随机推荐

  1. 移动 H5 首屏秒开优化方案探讨

    转载bang大神文章,原文<移动 H5 首屏秒开优化方案探讨>,此文仅仅用做自学与分享! 随着移动设备性能不断增强,web 页面的性能体验逐渐变得可以接受,又因为 web 开发模式的诸多好 ...

  2. 容易出错的JavaScript题目集锦

    容易出错的JavaScript题目集锦 1.typeof(null) 会得到什么?object,在JavaScript中null被认为是一个对象. 2.下列代码将输出控制台的是什么?为什么? 1234 ...

  3. 两种HTTP请求方法:GET和POST的区别

    之前在一些开发者平台使用网页调用API时,一再提到两种请求方法GET和POST,所以就去了解了下.那么这又不得不提到HTTP了! 一.什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户 ...

  4. Welcome to Giyber Blog - LC的博客

    "You can be the best! " 一切才刚开始 "不知道行不行,试试吧."抱着这样的理由,一个小白的成长记录,由此开始. 在 Mr.锤 的&quo ...

  5. 最近做的一个Spring Boot小项目,欢迎大家访问 http://39.97.115.152/

    最近做的一个Spring Boot小项目,欢迎大家访问 http://39.97.115.152/,帮忙找找bug,网站里有源码地址 网站说明 甲壳虫社区(Beetle Community) 一个开源 ...

  6. element ui table render-header自定义表头信息使用

    在使用vue自定义组件内容过程之中,我们绝大多数情况下都是通过预先写好不同的html模板,再通过props传入不同的值来渲染不同的模板.例如我们需要实现一个<v-title size='1'&g ...

  7. Dubbo 入门-细说分布式与集群

    什么是Dubbo Dubbo是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 什么是RPC RPC全称(Rem ...

  8. JZOJ 3928. 【NOIP2014模拟11.6】射击

    3928. [NOIP2014模拟11.6]射击 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 有问题, ...

  9. 基于JWT实现token验证

    JWT的介绍 Json Web Token(JWT)是目前比较流行的跨域认证解决方案,是一种基于JSON的开发标准,由于数据是可以经过签名加密的,比较安全可靠,一般用于前端和服务器之间传递信息,也可以 ...

  10. 结题报告--P5551洛谷--Chino的树学

    题目:点此 题目描述 Chino树是一棵具有某种性质的满二叉树,具体来说,对于这棵树的每一个非叶子节点,它的左子节点(A)(A)(A)的右子节点(C)(C)(C)与它的右子节点(B)(B)(B)的左子 ...