点击蓝字关注我们
课程链接:/course/explore
良心课程,大家一起来学习哈!
任务22:课程介绍
1.HTTP 处理过程
2.WebHost 的配置与启动
3.Middleware 与管道
4.Routing MiddleWare 介绍
任务23:Http请求的处理过程
任务24:WebHost的配置
1.覆盖配置文件
2.更改启动URL
3.IHostingEnvironment
4.IApplicationLifetime
5.dotnet watch run
dotnet new web
settings.json
"ConnectionStrings":{ "DefaultConnection":"Server=...;Database=...;" } }{
Program.cs
WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration(configureDelegate=>{ configureDelegate.AddJsonFile("settings.json"); }) .UseStartup<Startup>();public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { // await context.Response.WriteAsync("Hello World!"); // JsonFile await context.Response.WriteAsync(configuration["ConnectionStrings:DefaultConnection"]); }); }using Microsoft.Extensions.Configuration;
启动HelloCore,输出结果
Program.cs
WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration(configureDelegate => { //configureDelegate.AddJsonFile("settings.json"); configureDelegate.AddCommandLine(args); }) //.UseUrls("http://localhost:5001") .UseStartup<Startup>();public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
Startup.cs
{ // await context.Response.WriteAsync("Hello World!"); // JsonFile //await context.Response.WriteAsync(configuration["ConnectionStrings:DefaultConnection"]); // CommandLine await context.Response.WriteAsync($"name={configuration["name"]}"); });app.Run(async (context) =>
设置应用程序参数
启动HelloCore,输出结果
任务25:IHostEnvironment和 IApplicationLifetime介绍
Startup.cs
{ await context.Response.WriteAsync($"ContentRootPath = {env.ContentRootPath}"); await context.Response.WriteAsync($"EnvironmentName = {env.EnvironmentName}"); await context.Response.WriteAsync($"WebRootPath = {env.WebRootPath}"); });app.Run(async (context) =>
启动HelloCore,输出结果
Startup.cs
{ if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } applicationLifetime.ApplicationStarted.Register(() => { Console.WriteLine("Started"); }); applicationLifetime.ApplicationStopped.Register(() => { Console.WriteLine("Stopped"); }); applicationLifetime.ApplicationStopped.Register(() => { Console.WriteLine("Stopped"); }); app.Run(async (context) => { await context.Response.WriteAsync($"ContentRootPath = {env.ContentRootPath}"); await context.Response.WriteAsync($"EnvironmentName = {env.EnvironmentName}"); await context.Response.WriteAsync($"WebRootPath = {env.WebRootPath}"); }); }public void Configure(IApplicationBuilder app, IHostingEnvironment env, IConfiguration configuration, IApplicationLifetime applicationLifetime)
启动HelloCore,输出结果
我心中的 Core 新核心对象WebHost(一):
//11/11/aspnet-core-object-webhost/#comment-194
我心中的 Core 新核心对象WebHost(二):
//11/14/aspnet-core-object-webhost-build/
任务26:dotnet watch run 和attach到进程调试
New Terminal
dotnet new web --name HelloCore
F5 Start Debug
在csproj 的 ItemGroup 添加引用
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
New Terminal
dotnet watch rundotnet restore
修改代码保存后会自动重启
浏览器刷新即可看到更新结果
attach到进程调试
任务27:Middleware管道介绍
1.Middleware 与管道的概念
2.用 Middleware 来组成管道实践
3.管道的实现机制(RequestDelegate 与 ApplicationBuilder)
startup.cs
{ if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 添加一个中间件,传一个名字为next的request delegate app.Use(async (context,next)=>{ await context.Response.WriteAsync("1: before start..."); await next.Invoke(); }); // 接收一个RequestDelegate,返回一个RequestDelegate app.Use(next=>{ return (context)=>{ context.Response.WriteAsync("2: in the middle of start.."); return next(context); }; }); app.Run(async (context) => { await context.Response.WriteAsync("3: start..."); }); }public void Configure(IApplicationBuilder app, IHostingEnvironment env)
启动项目,输出结果
app.Use(next=>{ return (context)=>{ return context.Response.WriteAsync("2: in the middle of start.."); //return next(context); }; });// 如果不调用next,则管道终止,不会输出"3: start..."
app.Map("/task", taskApp=>{ taskApp.Run(async context=>{ await context.Response.WriteAsync("this is a task"); }); }); // 添加一个中间件,传一个名字为next的request delegate app.Use(async (context,next)=>{ await context.Response.WriteAsync("1: before start..."); await next.Invoke(); }); // 接收一个RequestDelegate,返回一个RequestDelegate // 如果不调用next,则管道终止,不会输出"3: start..." app.Use(next=>{ return (context)=>{ context.Response.WriteAsync("2: in the middle of start.."); return next(context); }; }); app.Run(async (context) => { await context.Response.WriteAsync("3: start..."); });// 使用Map构建路由,通过localhost:5000/task访问
访问 https://localhost:5001/task
任务28:RequestDelegate管道实现思路
1.RequestDelegate
2.ApplicationBuilder:多个RequestDelegate拼接
app.Use(async (context,next)=>{ await context.Response.WriteAsync("1: before start...");// 完成自己处理 await next.Invoke();// 调用下一步 }); // 封装一个function交给ApplicationBuilder处理 app.Use(next=>{ return (context)=>{ context.Response.WriteAsync("2: in the middle of start.."); return next(context); }; });// 添加一个中间件,传一个名字为next的RequestDelegate
任务29:自己动手构建RequestDelegate管道
新建一个控制台程序
dotnet new console --name MyPipeline
新建一个类RequestDelegate.cs
using System.Threading.Tasks; namespace MyPipeline { public delegate Task RequestDelegate(Context context); }using System;
新建一个类Context.cs
using System.Threading.Tasks; namespace MyPipeline { public class Context { } }using System;
using System.Collections.Generic; using System.Threading.Tasks; namespace MyPipeline { class Program { public static List<Func<RequestDelegate,RequestDelegate>> _list = new List<Func<RequestDelegate, RequestDelegate>>(); static void Main(string[] args) { Use(next=>{ return context=>{ Console.WriteLine("1"); return next.Invoke(context); }; }); Use(next=>{ return context=>{ Console.WriteLine("2"); return next.Invoke(context); }; }); RequestDelegate end = (Context)=>{ Console.WriteLine("end..."); return pletedTask; }; _list.Reverse(); foreach(var middleware in _list) { end = middleware.Invoke(end); } end.Invoke(new Context()); Console.ReadLine(); } public static void Use(Func<RequestDelegate,RequestDelegate> middleware) { _list.Add(middleware); } } }using System;
在任何一个Middleware可以结束管道
return context=>{ Console.WriteLine("1"); //return next.Invoke(context); return pletedTask;// 结束管道调用,只输出1 }; });Use(next=>{
任务30:RoutingMiddleware介绍以及MVC引入
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; namespace HelloCore { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit /fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddRouting();// 添加依赖注入配置 } // 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(); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 通过localhost:5000/action访问 app.UseRouter(builder=>builder.MapGet("action", async context=>{ await context.Response.WriteAsync("this is a action"); })); // 使用Map构建路由,通过localhost:5000/task访问 app.Map("/task", taskApp=>{ taskApp.Run(async context=>{ await context.Response.WriteAsync("this is a task"); }); }); // 添加一个中间件,传一个名字为next的request delegate app.Use(async (context,next)=>{ await context.Response.WriteAsync("1: before start..."); await next.Invoke(); }); // 如果不调用next,则管道终止,不会输出"3: start..." app.Use(next=>{ return (context)=>{ return context.Response.WriteAsync("2: in the middle of start.."); //return next(context); }; }); app.Run(async (context) => { await context.Response.WriteAsync("3: start..."); }); } } }using Microsoft.AspNetCore.Builder;
访问 https://localhost:5001/action
使用UseRouter方法2
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; namespace HelloCore { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit /fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddRouting();// 添加依赖注入配置 } // 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(); } if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 使用UseRouter方法2 // 通过localhost:5000/action访问 RequestDelegate handler = context=>context.Response.WriteAsync("this is a action"); var route = new Route( new RouteHandler(handler), "action", app.ApplicationServices.GetRequiredService<IInlineConstraintResolver>() ); app.UseRouter(route); // 使用UseRouter方法1 // 通过localhost:5000/action访问 app.UseRouter(builder=>builder.MapGet("action", async context=>{ await context.Response.WriteAsync("this is a action"); })); // 使用Map构建路由,通过localhost:5000/task访问 app.Map("/task", taskApp=>{ taskApp.Run(async context=>{ await context.Response.WriteAsync("this is a task"); }); }); // 添加一个中间件,传一个名字为next的request delegate app.Use(async (context,next)=>{ await context.Response.WriteAsync("1: before start..."); await next.Invoke(); }); // 如果不调用next,则管道终止,不会输出"3: start..." app.Use(next=>{ return (context)=>{ return context.Response.WriteAsync("2: in the middle of start.."); //return next(context); }; }); app.Run(async (context) => { await context.Response.WriteAsync("3: start..."); }); } } }using Microsoft.AspNetCore.Builder;
访问 https://localhost:5001/action
RountingMiddleware介绍
var route = new Route(routeHandler); new RouteMiddleware(route) RouteMiddleware.Invoke(httpContext) _route.RouteAsync(context) routeMatch(RouteContext) OnRouteMatched(RouteContext)var routeHandler = new RouteHandler(context=>context.Response.WriteAsync("test"));
点“在看”给我一朵小黄花