zoukankan      html  css  js  c++  java
  • 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 = 50; //异常显示行数
         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中的中间件吧。

  • 相关阅读:
    好友消息和群消息区别
    好友消息和群消息区别
    完整的微信登陆 接收消息流程
    完整的微信登陆 接收消息流程
    perl 对象 通过bless实现
    perl 对象 通过bless实现
    00019_数组的定义
    关于tinymce粘贴图片自动上传
    关于kindeditor粘贴图片自动上传
    关于ckeditor粘贴图片自动上传
  • 原文地址:https://www.cnblogs.com/jesen1315/p/11039251.html
Copyright © 2011-2022 走看看