Asp.Net Core 入门(二)——Startup.cs做了什么
上篇介绍了Program.cs中Main做了什么,这篇我们来讨论下Startup.cs它又做了什么呢?
我们新建一个Asp.Net Core Mvc项目,先来开一下Startup的代码
- 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.Configure<CookiePolicyOptions>(options =>
- {
- // This lambda determines whether user consent for non-essential cookies is needed for a given request.
- options.CheckConsentNeeded = context => true;
- options.MinimumSameSitePolicy = SameSiteMode.None;
- });
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
- }
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseExceptionHandler("/Home/Error");
- // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
- app.UseHsts();
- }
- app.UseHttpsRedirection();
- app.UseStaticFiles();
- app.UseCookiePolicy();
- app.UseMvc(routes =>
- {
- routes.MapRoute(
- name: "default",
- template: "{controller=Home}/{action=Index}/{id?}");
- });
- }
- }
Startup包含两个方法,我们先来分析一下ConfigureServices。通过方法上面的注释可以看到,这个方法是被.Net运行时调用的,实际上Asp.Net Core提供了内置的IOC容器,此方法就是用来将我们自己的服务Service注入到Ioc容器当中。那么如何注入呢?当然是利用该方法的参数IServiceCollection进行注入。如果是我们自定义的Service,可以使用services.AddTransient<IStudentRepository,MockStudentRepository>()或其他的两种方式Singleton/Scoped来注入,具体区别看下面代码。如果是注入.Net Core自带的,一般是使用AddMvc,AddCors()。
- public void ConfigureServices(IServiceCollection services)
- {
- //单例注入,创建的对象在所有的地方所有的请求会话创建的都是相同
- services.AddSingleton<IStudentRepository, MockStudentRepository>();
- //瞬时注入,每次都创建一个新的对象
- services.AddTransient<IStudentRepository, MockStudentRepository>();
- //作用域注入,创建的对象在同一个请求会话时是相同的
- services.AddScoped<IStudentRepository, MockStudentRepository>();
- //注入MVC模块,包含MvcCore和常用第三方库的服务和方法
- services.AddMvc();
- //只包含核心的Mvc功能
- services.AddMvcCore();
- }
接下来我们来看一下另一个方法Configure。它是用来配置Asp.Net Core Mvc的Http请求管道的。Asp.Net Core的http请求管道与我们之前的Asp.Net Mvc的请求管道有着很大的差别,它引入了中间件的概念,更像是一种责任链的模式。
现在我们就先来分析一下,参数IHostingEnvironment env,顾名思义是web宿主的环境变量相关的。在我们的实际开发中,我们常常会将我们的环境分成:开发环境development,继承环境integration,测试环境testing,预发布环境staging,生产环境production。那这个环境是怎么配置的呢?实际上它是通过 ASPNETCORE_ENVIRONMENT 这个环境变量来配置运行时的环境的。
一般我们的配置遵循:
1、开发机器上,可以在launchingsetting.json文件中设置该环境变量
2、在预发布环境staging或生产环境production下,尽量将该变量设置在操作系统中的环境变量里,因为上篇我们也讲到,Asp.Net Core启动读取变量配置的时候是会依次覆盖的。
3、除了Asp.Net Core提供的development,staging,production外,我们可以定义其他的环境,通过调用 env.IsEnvironment("自定义的环境变量");来判断是否处于此环境。
一般我们可以配置开发环境下显示错误的方式如下面代码。
- if (env.IsDevelopment())
- {
- DeveloperExceptionPageOptions developerExceptionPageOptions = new DeveloperExceptionPageOptions();
- developerExceptionPageOptions.SourceCodeLineCount = ; //异常显示行数
- app.UseDeveloperExceptionPage(); //开发者异常页面
- }
在我们继续往下看代码之前,先来了解一下Asp.Net Core的中间件这个概念。
中间件是组装到应用程序管道中以处理请求和响应的软件,Asp.Net Core自带了很多的中间件,可以看下下图展示的中间件,可以看到请求经过Logging -> StaticFiles -> MVC后处理完再从MVC -> StaticFiles -> Logging返回给调用方。
其中MVC为终端中间件,终端中间件表示执行完这个中间件的时候就已经结束了,不会再往下调用其他的管道中间件了,这也是我们创建完项目后看到最后一个是app.UseMvc的原因。
关于中间件我们需要注意的:
1、中间件可以同时被访问和请求
2、可以处理请求后,将请求传递给下一个中间件
3、可以处理请求后,使管道短路
4、可以处理传出响应
5、中间件是按照添加的顺序执行的
现在我们来具体分析下Configure里面是怎么配置管道的。IApplicationBuilder app 参数为我们提供了很多扩展方法,通过这些方法可以配置我们的中间件。首先我们来看Asp.Net Core提供的Use,Map,Run方法。
Use
方法可以使管道短路(即,可以不调用下一个中间件)。我们再Configure方法中调用app.Use方法,如果我们在该方法中不调用next()方法,那么请求到达该方法就结束返回了,不会再往下一个中间件执行,即后面的Run不会执行。
- app.Use(async (context, next) =>
- {
- context.Response.ContentType = "text/plain;charset=utf-8;"; //解决中文乱码
- await context.Response.WriteAsync("这是第一个Hello World");
- //await next(); //调用下一个中间件
- });
- app.Run(async (context) =>
- {
- //获取当前进程名
- await context.Response.WriteAsync( System.Diagnostics.Process.GetCurrentProcess().ProcessName);
- });
如果我们放开了next(),则会继续往下执行
再看一下下面的代码
- app.Use(async (context, next) =>
- {
- context.Response.ContentType = "text/plain;charset=utf-8;"; //解决中文乱码
- await context.Response.WriteAsync("Use1之前");
- await next(); //调用下一个中间件
- await context.Response.WriteAsync("Use1之后");
- });
- app.Use(async (context, next) =>
- {
- await context.Response.WriteAsync("Use2之前");
- await next(); //调用下一个中间件
- await context.Response.WriteAsync("Use2之后");
- });
- app.Run(async (context) =>
- {
- //获取当前进程名
- await context.Response.WriteAsync( System.Diagnostics.Process.GetCurrentProcess().ProcessName);
- });
我们可以看到,请求过来后,以链式的方式执行: Use1之前 --> next --> Use2之前 --> next --> Run --> Use2之后 --> Use1之前。
Run
方法是一个约定, 并且一些中间件组件可能暴露在管道末端运行的Run [Middleware]方法,如果将Run放在了Configure里面,它也是终端中间件。
- app.Run(async (context) =>
- {
- context.Response.ContentType = "text/plain;charset=utf-8;"; //解决中文乱码
- //获取当前进程名
- await context.Response.WriteAsync("当前进程名:" + System.Diagnostics.Process.GetCurrentProcess().ProcessName);
- });
Map*
扩展用作分支管道的约定。映射根据给定的请求路径的匹配来分支请求流水线,如果请求路径以给定路径开始,则执行分支。
- private static void HandleMapTest1(IApplicationBuilder app)
- {
- app.Run(async context =>
- {
- await context.Response.WriteAsync("Map Test 1");
- });
- }
- private static void HandleMapTest2(IApplicationBuilder app)
- {
- app.Run(async context =>
- {
- await context.Response.WriteAsync("Map Test 2");
- });
- }
- app.Map("/map1", HandleMapTest1);
- app.Map("/map2", HandleMapTest2);
最后我们再来看一下Asp.Net Core提供的一些其他的中间件。
- /*自定义默认页(第一种方式)*/
- //DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();
- //defaultFilesOptions.DefaultFileNames.Clear();
- //defaultFilesOptions.DefaultFileNames.Add("custom.html"); //自定义默认页
- //app.UseDefaultFiles(defaultFilesOptions);
- /**************************************************************************/
- /*自定义默认页(第二种方式)*/
- //FileServerOptions fileServerOptions = new FileServerOptions();
- //fileServerOptions.DefaultFilesOptions.DefaultFileNames.Clear();
- //fileServerOptions.DefaultFilesOptions.DefaultFileNames.Add("custom.html");
- //app.UseFileServer(fileServerOptions); //集合了UseStaticFiles,UseDefaultFiles,UseDirectoryBrowser
- /************************************************/
- //app.UseDefaultFiles(); //添加默认文件中间件,必须注册在UseStaticFiles前 index.html index.htm default.html default.htm
- app.UseStaticFiles(); //添加静态文件中间件
- //app.UseDirectoryBrowser();//暴露项目文件夹,不推荐使用
- app.UseMvcWithDefaultRoute();//在请求管道中添加带默认路由的MVC
好了,这篇博文介绍了Startup文件做了哪些事情,其中最重要的就是中间件,那么下一篇就来聊聊Asp.Net Corez中的中间件吧。
Asp.Net Core 入门(二)——Startup.cs做了什么的更多相关文章
- ASP.NET Core 入门教程 10、ASP.NET Core 日志记录(NLog)入门
一.前言 1.本教程主要内容 ASP.NET Core + 内置日志组件记录控制台日志 ASP.NET Core + NLog 按天记录本地日志 ASP.NET Core + NLog 将日志按自定义 ...
- ASP.NET Core入门(一)
大家好,很荣幸您点了开此篇文章,和我一起来学习ASP.NET Core,此篇文字为<ASP.NET Core入门>系列中的第一篇,本系列将以一个博客系统为例,从第一行代码,到系统发布上线( ...
- ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 项目配置 ( Startup ) - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 项目配置 ( Startup ) 前面几章节 ...
- CentOS开发ASP.NET Core入门教程
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9891346.html 因为之前一直没怎么玩过CentOS,大多数时间都是使用Win10进行开发,然后程序 ...
- asp.net core 系列之Startup
这篇文章简单记录 ASP.NET Core中 ,startup类的一些使用. 一.前言 在 Startup类中,一般有两个方法: ConfigureServices 方法: 用来配置应用的 servi ...
- ASP.NET CORE 入门教程(附源码)
ASP.NET CORE 入门教程 第一课 基本概念 基本概念 Asp.Net Core Mvc是.NET Core平台下的一种Web应用开发框架 符合Web应用特点 .NET Core跨平台解决方案 ...
- 小白开学Asp.Net Core《二》(补)
小白开学Asp.Net Core<二>(补) ——数据仓储层(Repositroy).服务层(Service) -------------------------------------- ...
- 【翻译】ASP.NET Core 入门
ASP.NET Core 入门 原文地址:Introduction to ASP.NET Core 译文地址:asp.net core 简介 翻译:ganqiyin ...
- 小白开学Asp.Net Core《二》
小白开学Asp.Net Core<二> ——数据仓储层(Repositroy) 一.历史现象 在后端开发中,数据库操作是最频繁的,每一个开发人员都会接触,甚至不少开发人员每天的工作就是与数 ...
随机推荐
- PostgreSQ 连接问题 FATAL: no pg_hba.conf entry for host
PostgreSQ数据库为了安全,它不会监听除本地以外的所有连接请求,当用户通过JDBC访问是,会报一些如下的异常: org.postgresql.util.PSQLException: FATAL: ...
- .NETFramework:Cache
ylbtech-.NETFramework:Cache 1.返回顶部 1. #region 程序集 System.Web, Version=4.0.0.0, Culture=neutral, Publ ...
- 使用FPDF输出中文
① 下载FPDF相关资料=>https://github.com/DCgithub21/cd_FPDF ② 查看目录文件 注:ttf2pt1.zip为字体转换程序 ③ 运行example.ph ...
- 利用记事本和cmd进行java编程(从安装IDE--编译--运行)
java 最大特点---跨平台 所谓的跨平台性,是指软件可以不受计算机硬件和操作系统的约束而在任意计算机环境下正常运行.这是软件发展的趋势和编程人员追求的目标.之所以这样说,是因为计算机硬件的种类繁多 ...
- MySQL命令行参数
一,mysql命令行参数 Usage: mysql [OPTIONS] [database] //命令方式 -?, --help //显示帮助信息并退出 -I, --help ...
- [Vue 牛刀小试]:第十二章 - 使用 Vue Router 实现 Vue 中的前端路由控制
一.前言 前端路由是什么?如果你之前从事的是后端的工作,或者虽然有接触前端,但是并没有使用到单页面应用的话,这个概念对你来说还是会很陌生的.那么,为什么会在单页面应用中存在这么一个概念,以及,前端路由 ...
- Moctf--没时间解释了
记录一道简单的题目. 打开后就张这个样子,,然后看到url为index2.php---->所以我们把它改为index.php(用burp抓包才行,这是一个302跳转). 看到它提示我们要uplo ...
- Vue生命周期简介和钩子函数
钩子就好像是把人的出生到死亡分成一个个阶段,你肯定是在出生阶段起名字,而不会在成年或者死亡的阶段去起名字.或者说你想在出生阶段去约炮,也是不行的.组件也是一样,每个阶段它的内部构造是不一样的.所以一般 ...
- Access 中case when then else end不支持使用switch代替
Access 中case when then else end不支持使用switch代替 这里主要是实现一个表中多个字段,多个字段之间作比较然后取得最大值或者最小值用来处理 case when the ...
- elasticsearch接口开发(新)
此文在上一篇文章的基础上稍做了些许修改,主要在springboot整合ES后的包路径上,如下是新的目录结构 下面贴出代码 MyConfig.java package com.ylht.config; ...