ASP.NET Core 运行原理剖析

2023-10-27

1.1. 概述

在ASP.NET Core之前,ASP.NET Framework应用程序由IIS加载。Web应用程序的入口点由InetMgr.exe创建并调用托管。以初始化过程中触发HttpApplication.Application_Start()事件。开发人员第一次执行代码的机会是处理Application_StartGlobal.asax中的事件。在ASP.NET Core中,Global.asax文件不再可用,已被新的初始化过程替代。

 

ASP.NET Core 应用程序是在.NET Core 控制台程序下调用特定的库,这是ASP.NET Core应用程序开发的根本变化。所有的ASP.NET托管库都是从Program开始执行,而不是由IIS托管。也就是说.NET工具链可以同时用于.NET Core控制台应用程序和ASP.NET Core应用程序。

using System;
using Microsoft.AspNetCore.Hosting;

namespace aspnetcoreapp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            
            var host = new WebHostBuilder()
                .UseKestrel() //指定宿主程序为Kestrel
                .UseStartup<Startup>()// 调用Startup.cs类下的Configure 和 ConfigureServices
                .Build();

            host.Run();
        }
    }
}

以上是Program类中Main方法的示例代码,Main方法负责初始化Web主机,调用Startup和执行应用程序。主机将调用Startup类下面的ConfigureConfigureServices方法。

1.2. 文件配置

1.2.1. Starup文件配置

对于一个ASP.NET Core 程序而言,Startup 类非必须,其只是提供了一个更友好的方式进行依赖注入和中间件注册。
其命名没有限制,约定使用Startup。

ASP.NET Core在程序启动时会从Program类中开始执行,然后再找到UseStartup<Startup>中找到配置的Startup的类,如果不指定Startup类会导致启动失败。

Startup中必须定义Configure方法,而ConfigureServices方法则是可选的,方法会在程序第一次启动时被调用,类似传统的ASP.NET MVC的路由和应用程序状态均可在Startup中配置,也可以在此初始化所需中间件。

Configure

在ASP.NET Core 应用程序中Configure方法用于指定中间件以什么样的形式响应HTTP请求。


using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace aspnetcoreapp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
                        
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            
            app.UseStaticFiles();
                                    
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

ASP.NET Core是通过对IApplicationBuilder进行扩展来构建中间件的, 上面代码中每个use扩展方法都是将中间件添加到请求管道。也可以给Configure方法附加服务(如:IHostingEnvironment)这些服务在ConfigureServices方法中被初始化。

用ASP.NET Core项目模板添加的应用程序,默认添加的几个中间件:

  • UseStaticFiles 允许应用程序提供静态资源。
  • UseMvc 将MVC添加到管道并允许配置路由。

ConfigureServices

ConfigureServices方法是应用程序运行时将服务添加到容器中,用ASP.NET Core项目模板的时候默认会将MVC的服务添加到容器中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

接下来举一个例子,在实际应用中ConfigureServices方法和Configure方法配合使用,在ASP.NET Core中有一个UI开发框架Telerik UI for ASP.NET Core,它有60多个UI组件,不仅支持ASP.NET Core的跨平台布署模式,而且还支持前端自适应渲染。

当在项目中应用Telerik UI的时候,首先在项目中引用相关的包,然后再在ConfigureServices方法中将Kendo UI服务添加到容器中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddKendo();
}

接下来,在Configure中设置Kendo UI

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...
    app.UseKendo(env);
}

1.2.2. appsetting.json配置

Configuration API 提供了一个基于键-值对来配置应用程序的方法,在运行时可以从多个来源来读取配置。键-值对可以分组形成多层结构。键-值对可以配置在不同的地方,如:文件、内存等,其中放在内存中不能持久化,这里笔者选择将其配置在appsetting.json文件里面。

配置appsetting文件


{
  "key1": "字符串",
  "key2": 2,
  "key3":true,

  "parentObj": {
    "key1": "sub-key1"
  },
  "members": [
    {
      "name": "Lily",
      "age": "18"
    },
    {
      "name": "Lucy",
      "age": "17"
    }
  ]
}

一个分层结构的JSON文件,键(如:key1)作为索引器,值作为参数,类型可以为:字符串、数字、布尔、对象、数组。下面具体来看下在应用中怎样使用。

在应用程序加加载和应用配置文件


public static IConfigurationRoot Configuration { get; set; }

public static void Main(string[] args = null)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json");

    Configuration = builder.Build();

    Console.WriteLine($"key1 = {Configuration["key1"]}");
    Console.WriteLine($"key2 = {Configuration["key2"]}");
    Console.WriteLine(
        $"subkey1 = {Configuration["parentObj:key1"]}");
    Console.WriteLine();

    Console.WriteLine("members:");
    Console.Write($"{Configuration["members:0:name"]}, ");
    Console.WriteLine($"age {Configuration["members:0:age"]}");
    Console.Write($"{Configuration["members:1:name"]}, ");
    Console.WriteLine($"age {Configuration["members:1:age"]}");
    Console.WriteLine();

    Console.WriteLine("Press a key...");
    Console.ReadKey();
}

由于加载的是一个JSON文件,所以文件加载进来以后程序可以直接将它当作一个JSON对象来使用。如果有过动态语言使用经验的同学来说这种方式就比较熟悉了。只在这里访问属性的时候将平时常见的.变成了:,这和写的JSON对象更接近。

1.3. 处理管道(中间件)

在ASP.NET Core应用程序中使用中间件,应用程序所做的任何事情(包括服务器中的静态文件)都是由中间件来完成的。没有任何中间件的应用程序在请求的出错时候简单返回404 Not Found。中间件可以让您完全控制请求的处理方式,并且让您的应用程序更加精简。

当接收到一个请求时,请求会交给中间件构成的中间件管道进行处理,管道就是多个中间件构成,请求从一个中间件的一端进入,从中间件的另一端出来,每个中间件都可以对HttpContext请求开始和结束进行处理:

 

在ASP.NET Core中可以用Run、Map和Use三种方式来配置HTTP管道。Run 方法称为短路管道(因为它不会调用 next 请求委托)。因此,Run方法一般在管道尾部被调用。Run 是一种惯例,有些中间件组件可能会暴露他们自己的 Run方法,而这些方法只能在管道末尾处运行。下面两段代码是等效的,因为Use没有调用next方法

Run方法示例代码

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

    app.Run(async context =>
        {
            await context.Response.WriteAsync("environment " + env);
        });

}

Use方法不执行next时示例代码

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

    app.Use(async (context, next) =>
        {
            await context.Response.WriteAsync("environment " + env);
        });

}

在.NET Core 中约定了Map*扩展被用于分支管道,当前的实现已支持基于请求路径或使用谓词来进入分支。Map扩展方法用于匹配基于请求路径的请求委托。Map只接受路径,并配置单独的中间件管道的功能。


private static void HandleMapUrl(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Url Test Successful");
    });
}
public void ConfigureMapping(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Map("/mapurl", HandleMapUrl);
}

上例中是一个用Map方法来接受路径进入分支管道,也就是说所有基于/mapurl路径请求都会被管道中的HandleMapUrl方法所处理;如果想用谓词来进入中间件分支,则要使用MapThen方法。MapThen方法允许以一种非常灵活的方式构建中间管道。比如可以检测查询字符串是否具有'branch'来进入分支:

private static void HandleBranch(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Branch used.");
    });
}
public void Configure(IApplicationBuilder app)
{
    app.MapWhen(context => {
        return context.Request.Query.ContainsKey("branch");
    }, HandleBranch);

}

1.4 总结

  • 这节讲解了ASP.NET Core在运行时首先加载Program类下面的Main方法,在Main方法中指定托管服务器,并调用Startup类中的ConfigureConfigureServices方法等完成初始化;
  • 在ASP.NET Core中 HTTP请求是以中间件管道的形式进行处理,每个中间件都可以在HTTP请求开始和结束处理对它进行处理;
  • ASP.NET Core可以构建跨平台应用,服务运行在Http.Sys(仅适用于Windows平台)和Kestrel上,不需要用IIS进行托管,所以相比传统ASP.NET来说性能更高效也更加灵活。

转载注明出处http://www.cnblogs.com/vipyoumay/p/7567573.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET Core 运行原理剖析 的相关文章

  • 如何在 Ubuntu 20.04 上安装 Dotnet Core

    NET Core 是一个免费的开源软件框架 其设计时考虑了 Linux 和 macOS 它是 NET Framework 的跨平台继承者 适用于 Linux macOS 和 Windows 系统 NET Core 框架已经提供了用于引导项目
  • ASP.NET Core 运行原理剖析

    1 ASP NET Core 运行原理剖析 1 1 概述 1 2 文件配置 1 2 1 Starup文件配置 Configure ConfigureServices 1 2 2 appsetting json配置 1 3 处理管道 中间件
  • C# 计算两个日期之间的所有日期

    用一个for循环就可以解决 int year Begin Convert ToInt32 this dateBegin Value ToString yyyy int month Begin Convert ToInt32 this dat
  • net core 建立webservice项目

    1 创建项目 2 通过NuGet安装SoapCore 3 创建服务接口及实现类 本项目会创建2个webservice服务文件用于测试 所以创建了2个model类和2个接口文件 Model类 DataContract public class
  • C# 如何向String[]字符数组插入数据

    C 如何向String 字符数组插入数据 思路 了解 由于数组是非动态的 不能进行动态的添加 思路 首先将string 字符数组转换成list 第二给list添加数据 最后把list转换成string 数组 String arrs new
  • 手把手教你搭建使用NuGet私有源

    文章目录 前言 Who 什么是NuGet Why 为什么用NuGet How 怎么使用NuGet 搭建Nuget私有源 打包Nuget包 发布到私有源 不开启密钥验证 开启密钥验证 测试 总结 前言 相信写过 net的小伙伴应该都用过NuG
  • Net Core 服务器占用内存过高

    高级语言一般都有垃圾回收机制 不用的内存会自己回收掉 当出现占用过高 可能代码不够好 主要还是代码优化 net core这里也有些设置可以不会让服务器崩盘 打开项目文件XXX csproj 在PropertyGroup节点加入
  • 记录一次Nginx转发请求给Ocelot网关响应500错误排查

    先说明下我们的Http请求流转及系统部署方式 当Http请求发起时 会先到达Nginx 然后Nignx会将请求转发至Ocelot网关服务 Ocelot网关服务会再将请求转发给下游真实提供API服务的应用 我们的应用是基于Net Core 3
  • .NET Core使用EF Core框架

    文章目录 概述 安装EF Core 使用EF Core增删改查 单表查询 插入数据 修改数据 删除数据 概述 Entity Framework EF Core 是轻量化 可扩展 开源和跨平台版的常用 Entity Framework 数据访
  • .Net Core下简单的JWT黑名单中间件

    自从JWT认证方式在互联网上蔓延后 Session认证方式就被挤掉了一大半的生存空间 这里我们不讲JWT与Session两种方式的优缺点 我们只讲如何通过JWT的黑名单来阻止某些Token的登录 设置黑名单 也就是说要将Token写入某个存
  • centso7 openssl 报错Verify return code: 20 (unable to get local issuer certificate)

    问题重现 由于centos7 默认的openssl的版本为1 1 0k 本人编译媒体服务时 需要openssl版本1 1 1以上 所有删除的之前的低版本openssl 手动编译了一个1 1 1k的版本 媒体服务正常运行 并且CA验证正常 结
  • 什么是.NET?什么是.NET Core?.NET和.NET Core区别又是什么呢?

    本文首发于码友网 什么是 NET 什么是 NET Core NET和 NET Core区别又是什么呢 概述 对于 NET平台的初学者来说 有时候比较困惑 什么是 NET 什么是 NET Core NET和 NET Core区别又是什么呢 确
  • .net core 连接Mysql

    1 安装依赖包 在这里插入图片描述 https img blog csdnimg cn 16e74e954c414688b26af8b9d92fd793 png x oss process image watermark type d3F5
  • .Net Core跨域处理

    查看官方文档 https docs microsoft com zh cn aspnet core security cors view aspnetcore 2 2 分两部分处理跨域 ConfigureServices里添加 servic
  • C#使用欧姆龙PLC的Fins协议读写PLC地址(基本封装)

    FINS通讯概述 FINS factory interface network service 通信协议是欧姆龙公司开发的用于工业自动化控制网络的指令 响应系统 运用 FINS指令可实现各种网络间的无缝通信 通过编程发送FINS指令 上位机
  • .NET Core:搭建私有Nuget服务器以及打包发布Nuget包

    使用docker搭建私有Nuget服务器 docker run d p 8080 80 v PWD nuget db var www db v PWD nuget packages var www packagefiles e NUGET
  • .NET Core 获取自定义配置文件信息(多种方式)

    引用 Microsoft AspNetCore App 元包或将包引用添加到 Microsoft Extensions Options ConfigurationExtensions 包 简而言之 直接可以用 Appsetting json
  • 在 ASP.NET Core 应用程序启动时运行代码的 3 种方法

    开发人员应该将初始化内存缓存的代码放在哪里 开发人员可能会发现有必要在 ASP NET Core 应用程序启动时只执行一次代码 例如 开发人员可能需要填充内存缓存 运行后台任务 从某些外部源读取配置 发布应用程序成功启动的事件等 ASP N
  • 简述关于ASP.NET MVC与.NET CORE 的区别

    简述关于ASP NET MVC与 NET CORE的区别 1 关于ASP NET 关于MVC 刚开始接触这个技术的时候我经常不理解他们的名字 我相信许多学ASP NET开发人员开始接触MVC应该也和我一样产生很多为什么 也会误认为认为MVC
  • .Net项目github接入sonarcloud

    代码质量方面的检测工具 在这之前从来没用过 就算前阵子听说了sonarcloud 也仅当知道记录了下 结果昨天被某些事情刺激了下 于是去查了下资料 然后就顺便在github上做了下测试 这里做个记录 sonarcloud的官网地址是http

随机推荐

  • vue字符串展示不同信息用逗号分隔

    效果图 原始图 直接上代码 表格数据
  • Linux安装negix

    本文章介绍了在CentOS7 9 64位系统下 安装neginx 1 20 2版本 注意红色字体都是我踩的坑 目录 第一步 下载negix和安装依赖 第二步 解压安装 第三步 执行配置命令 第四步 编译和安装 第五步 启动nginx 第六步
  • Unity -- 物体运动到某个地方自动销毁的实现 && 物体在某个点无限生成

    文章目录 物体运动到某个地方自动销毁 物体在某个点无限生成 创建空出生点 写随机生成的脚本 物体运动到某个地方自动销毁 using System Collections using System Collections Generic us
  • 文档管理存储服务器,管理存储服务器

    管理存储服务器 内容精选 换一换 云服务器备份在支持崩溃一致性备份的基础上 同时支持数据库备份 文件 磁盘数据在同一时间点 通过数据库备份内存数据 能够保证应用系统一致性 如包含MySQL或SAP HANA数据库的弹性云服务器 暂不支持集群
  • 【C#】.Net Framework框架下的Authorize权限类

    2023年 第31周 第3篇文章 给自己一个目标 然后坚持总会有收货 不信你试试 在C 的 NET Framework中 你可以使用Authorize类来处理权限认证 Authorize类位于System Web Mvc命名空间中 它提供了
  • python对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是: 00000 00001 00010 00011 00100 请按从小到大的顺序输出这32种

    for i in range 32 a 0 0 gt 5b format i print a
  • JAVA安装详细教程

    JAVA安装详细教程 JAVA安装总共分为三部分 一 下载JAVA安装包并安装JAVA 二 电脑环境设置 三 验证Java是否安装成功 一 下载JAVA安装包并安装JAVA 1 首先去官网现在JAVA安装包 JAVA安装包下载地址 http
  • Vue实例——百度搜索案例

    Vue实例 百度搜索案例 vue作为前端开发的渐进式框架 不仅比jQuery更加简洁 而且功能更为强大 接下来我将用vue js给大家介绍一个运用搜索框实现百度搜索的功能 开始之前我需要讲解一下百度搜索的数据传递流程 首先我们进百度搜索网站
  • Windows10下安装VMware16虚拟机

    前记 由于本人系统为Windows 10 家庭中文版 无法安装Linux子系统WSL 虽然网上也有强制安装的方法 但为保险起见 还是把之前的VMware虚拟机重新进行安装 并浅浅记录一下安装过程 一 VMware虚拟机的下载 下载 VMwa
  • qvariant是如何和稀泥的

    unionData char c uchar uc short s signedchar sc ushort us int i uint u long l ulong ul bool b double d float f qreal rea
  • 原地删除数组中的指定元素

    题目 给你一个数组 nums 和一个值 val 你需要 原地 移除所有数值等于 val 的元素 并返回移除后数组的新长度 示例 1 输入 nums 3 2 2 3 val 3 输出 2 nums 2 2 解释 函数应该返回新的长度 2 并且
  • 【deep_thoughts】48_快速复现PyTorch的Weight Normalization

    文章目录 理论 代码 全连接层 卷积层 视频链接 48 快速复现PyTorch的Weight Normalization 哔哩哔哩 bilibili 官方API torch nn utils weight norm 原始论文 Weight
  • declared implicitly

    declared implicitly 警告 h文件中未声明 如果还是不行 也可以把函数名改了试试
  • 虚拟交换机工作原理

    一 虚拟交换机概述 1 虚拟交换机简介 Switch Virtual Switch 指虚拟交换机或虚拟网络交换机 工作在二层数据网络 通过软件方式实现物理交换机的二层 和部分三层 网络功能 与传统物理交换机相比 虚拟交换机具备的优点 配置灵
  • 谷歌浏览器设置点击链接时打开新窗口

    根据谷歌浏览器的版本而定 我的是 步骤 1 右上角三个点的地方 选设置 2 外观 显示 主页 按钮选 打开新的标签页 OK设置完成
  • 详解大模型微调方法LoRA Adapter(内附实现代码)

    LoRA论文地址 LORA LOW RANK ADAPTATION OF LARGE LANGUAGE MODELS 1 背景介绍 以GPT 3 175B参数量为例 过大的参数量在Finetune的时候代价很大 Adapter适配器方法是进
  • STM32(六)库函数串口发送与接收实例(中断)

    STM系列文章目录 文章目录 STM系列文章目录 前言 一 串口配置步骤 二 实际编写 1 代码部分 重定向fputc函数 GPIO 前言 本篇用库函数写个简单的串口收发 用的是 STM32F103RCT6 开发板 部分来自正点原子 STM
  • rtsp实例及讲解

    rtsp是real time streaming protocol 按照我的理解为流媒体控制协议 协议双方的的编码类型和地址 以及对stream media的控制 play pause record 注意这里不要与RTCP协议搞混 rtcp
  • Mysql—修改用户密码(重置密码)

    Mysql 修改用户密码 重置密码 1 登录mysql 1 2 root localhost mysql uroot p123456 root localhost mysql hlocalhost uroot p123456 如果忘记密码
  • ASP.NET Core 运行原理剖析

    1 ASP NET Core 运行原理剖析 1 1 概述 1 2 文件配置 1 2 1 Starup文件配置 Configure ConfigureServices 1 2 2 appsetting json配置 1 3 处理管道 中间件