ASP.NET Core 四: Web核心与项目配置,静态内容(文件传输,npm包管理器),中间件,配置(环境配置,启动配置,用户密匙)
概念说明:
web核心,本质是一个集成了为Http请求服务功能的承载(Host),一个请求(request)和对应的响应(response)都由HttpContext对象表示。因此就可以在服务的Run程序中对HttpContext的对象做出相关的操作(即对request和response做操作)。
静态内容,这里是关于如何返回静态文件,如html文件,或者图片等。而npm则类似nuget,只不过npm主要用于javascript相关包的管理。
中间件,即对HttpContext进行管道化,或者称为流水线化的操作,可以认为Run方法是管道的最后一节,这样可以使得不用什么操作都放到Run方法中进行。
配置,环境配置是关于json配置文件,启动设置的配置文件(即Properties文件夹下的launchSetting.json文件);用户密匙的原理,即例如用户的如数据库连接字符串放在json配置文件里面是不安全的,需要进行另外处理。
重点:Web技术(Html,Css,JavaScript,TypeScript,ECMAScript),静态文件(wwwroot下的文件,Javascript包管理器),请求和响应(请求信息,请求标题,查询字符串(Get),编码(即普通字符串和html字符的转换),表单(Post),Cookie,发送Json,会话状态(Session)),项目配置(json配置文件,项目配置文件和用户密匙)
Web核心
下面是Demo的程序和运行结果,这是建立Asp .net core web空项目模板改写。运行的结果就是context将写入的text组装成html格式的代码返回给客户端。
同时,进一步操作可以从HttpContext对象可以获得request的信息,并且根据请求的信息将要返回的信息写入到response中返回给客户端,比如业务信息。
public class Startup { public void ConfigureServices(IServiceCollection services) { } //Http请求的执行管道 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.Run(async (context) => { await context.Response.WriteAsync("<div> Hello World </div>" + "Hello");//将内容写入到response中返回给客户端 }); } }
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>(); }); }
项目启动配置
打开启动配置文件可以看到所有的启动配置。同时这些配置可以在属性窗口,调试信息面板中看到
启动文件中iisSettings=>iisExpresss是用iis启动的时候的web访问路径地址。profiles下是不同的选择:IISExpress启动和项目启动。项目启动下的ApplicationUrl是从项目启动时的web访问地址,可以同时设置多个不同的地址;相对的IIS Express不用设置,因为已经在iisSettings设置。
判断环境变量的方式如下,参考博客ASP.NET Core-Environment、IWebHostEnvironment、IApplicationLifetime - 9.0 - 博客园 (cnblogs.com),当然不一定要按照启动文件设置判定,也可以通过其他json配置文件,读取方式已经在本博客系列二中演示过,这里不在赘述。
System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");//读取环境变量 env.IsDevelopment();//是否开发环境,ASPNETCORE_ENVIRONMENT环境变量值是否是Development env.IsProduction();//是否生产环境,ASPNETCORE_ENVIRONMENT环境变量值是否是Production env.IsStaging();//是否测试环境,ASPNETCORE_ENVIRONMENT环境变量值是否是Staging env.IsEnvironment("ok");//ASPNETCORE_ENVIRONMENT环境变量值是否是ok
静态内容(即Html)
程序需要添加中间件app.UseStaticFiles(),代码如下,可以看到,当程序执行到这里时,将不再往下执行,而是返回对应的文件内容,即html。一般可访问文件包括前端库和css文件等都是放在wwwroot文件夹下
//Http请求的执行管道 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseStaticFiles(); app.Run(async (context) => { await context.Response.WriteAsync("<div> Hello World </div>" + "Hello"); }); }
前端库工具:NPM,guilp
不知道是不时网络的问题,npm总是安装库失败,因此这里不在讨论,比较有效的方式直接上相关库的官方网站,直接下载库,然后手动复制放到wwwroot文件夹中。关于guilp,手动(TODO),暂时不需要,所以目前不讨论。
中间件
中间件的顺序是很重要的。它决定了管道的执行顺序。下面借了一张图(侵删)
下面是三个中间件A,B,C三个中间件的运行结果,可以看出context.Abort()方法会阻止后面的程序继续对context的操作,并且Wirte方法是以append的形式添加内容,而不是覆盖,当访问时html文件时,中间件的操作会使得返回结果为空。具体细节这里暂时不考虑,编程开发过程以根据官方文档为主(官方每年开发这么多框架,要是不断纠结还不累死)。
//中间件A public class AAMid { private readonly RequestDelegate _next; public AAMid(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { httpContext.Response.WriteAsync("AAMid=> "); return _next(httpContext); } } public static class AAMidExtensions { public static IApplicationBuilder UseAAMid(this IApplicationBuilder builder) { return builder.UseMiddleware<AAMid>(); } }
//中间件B public class BBMid { private readonly RequestDelegate _next; public BBMid(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { httpContext.Response.WriteAsync("BBMid=> "); return _next(httpContext); } } public static class BBMidExtensions { public static IApplicationBuilder UseBBMid(this IApplicationBuilder builder) { return builder.UseMiddleware<BBMid>(); } }
//中间件C public class CCMid { private readonly RequestDelegate _next; public CCMid(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { httpContext.Response.WriteAsync("CCMid=> "); httpContext.Abort(); return _next(httpContext); } } public static class CCMidExtensions { public static IApplicationBuilder UseCCMid(this IApplicationBuilder builder) { return builder.UseMiddleware<CCMid>(); } }
运行结果1
//Http请求的执行管道 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseAAMid();//中间件A app.UseBBMid();//中间件B //app.UseCCMid();//中间件C //app.UseStaticFiles(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World"); }); }
运行结果2
//Http请求的执行管道 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseAAMid();//中间件A app.UseBBMid();//中间件B app.UseCCMid();//中间件C //app.UseStaticFiles(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World"); }); }
运行结果3
//Http请求的执行管道 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseAAMid();//中间件A app.UseBBMid();//中间件B //app.UseCCMid();//中间件C app.UseStaticFiles(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World"); }); }
用户密匙
这个本质上不属于aspnet core的核心部分,就像是官方为了给开发者解决这方面的问题省事帮忙开发的一个小程序,由于开发过程中没使用过,因此这里只作为提点一下。
具体操作过程可以查看官方文档,如下,这里简单叙述一下。命令的操作需要在项目所在文件夹下进行,因为init命令会将secretid保存在项目文件中。secretid就是这个项目的secret.json所在的文件夹的名称。所以程序获取所需字符串,比如数据库连接字符串的过程就是,先通过项目secretid,找到对应的secret.json所在的文件夹,从这个文件夹下得到secret.json,最后从这个json文件中取出需要的字符串。