当前位置: 首页 > news >正文

网站建设ui设计网站建设公司方案

网站建设ui设计,网站建设公司方案,设计师常备设计网站大全,成都网站建设制作设计前言中间件(Middleware)对于Asp.NetCore项目来说#xff0c;不能说重要#xff0c;而是不能缺少#xff0c;因为Asp.NetCore的请求管道就是通过一系列的中间件组成的#xff1b;在服务器接收到请求之后#xff0c;请求会经过请求管道进行相关的过滤或处理#xff1b;正文… 前言中间件(Middleware)对于Asp.NetCore项目来说不能说重要而是不能缺少因为Asp.NetCore的请求管道就是通过一系列的中间件组成的在服务器接收到请求之后请求会经过请求管道进行相关的过滤或处理正文那中间件是那路大神会经常听说需要注册一下中间件如图所以说中间件是针对请求进行某种功能需求封装的组件而这个组件可以控制是否继续执行下一个中间件如上图中的app.UserStaticFiles()就是注册静态文件处理的中间件在请求管道中就会处理对应的请求如果没有静态文件中间件那就处理不了静态文件(如html、css等)这也是Asp.NetCore与Asp.Net不一样的地方前者是根据需求添加对应的中间件而后者是提前就全部准备好了不管用不用反正都要路过这也是Asp.NetCore性能比较好的原因之一而对于中间件执行逻辑官方有一个经典的图如图所示请求管道由一个个中间件(Middleware)组成每个中间件可以在请求和响应中进行相关的逻辑处理在有需要的情况下当前的中间件可以不传递到下一个中间件从而实现断路如果这个不太好理解如下图每层外圈代表一个中间件黑圈代表最终的Action方法当请求过来时会依次经过中间件Action处理完成后返回响应时也依次经过对应的中间件而执行的顺序如箭头所示(这里省去了一些其他逻辑只说中间件)。好了好了理论说不好担心把看到的小伙伴绕进去了就先到这吧接下来从代码中看看中间件及请求管道是如何实现的老规矩找不到下手的地方就先找能摸的到的地方这里就先扒静态文件的中间件namespace Microsoft.AspNetCore.Builder {public static class StaticFileExtensions{// 调用就是这个扩展方法public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app){if (app null){throw new ArgumentNullException(nameof(app));}// 这里调用了 IApplicationBuilder 的扩展方法return app.UseMiddlewareStaticFileMiddleware();}// 这里省略了两个重载方法是可以指定参数的} } UseMiddleware方法实现// 看着调用的方法 public static IApplicationBuilder UseMiddlewareTMiddleware(this IApplicationBuilder app, params object[] args) {// 内部调用了以下方法return app.UseMiddleware(typeof(TMiddleware), args); } // 其实这里是对自定义中间件的注册这里可以不用太深入了解 public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, Type middleware, params object[] args) {if (typeof(IMiddleware).GetTypeInfo().IsAssignableFrom(middleware.GetTypeInfo())){// IMiddleware doesnt support passing args directly since its// activated from the containerif (args.Length 0){throw new NotSupportedException(Resources.FormatException_UseMiddlewareExplicitArgumentsNotSupported(typeof(IMiddleware)));}return UseMiddlewareInterface(app, middleware);}// 取得容器var applicationServices app.ApplicationServices;// 反编译进行包装成注册中间件的样子(FuncReuqestDelegate,RequestDelegate)但可以看到本质使用IApplicationBuilder中Use方法return app.Use(next {// 获取指定类型中的方法列表var methods middleware.GetMethods(BindingFlags.Instance | BindingFlags.Public);// 找出名字是Invoke或是InvokeAsync的方法var invokeMethods methods.Where(m string.Equals(m.Name, InvokeMethodName, StringComparison.Ordinal)|| string.Equals(m.Name, InvokeAsyncMethodName, StringComparison.Ordinal)).ToArray();// 如果有多个方法 就抛出异常这里保证方法的唯一if (invokeMethods.Length 1){throw new InvalidOperationException(Resources.FormatException_UseMiddleMutlipleInvokes(InvokeMethodName, InvokeAsyncMethodName));}// 如果没有找到也就抛出异常if (invokeMethods.Length 0){throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoInvokeMethod(InvokeMethodName, InvokeAsyncMethodName, middleware));}// 取得唯一的方法Invoke或是InvokeAsync方法var methodInfo invokeMethods[0];// 判断类型是否返回Task,如果不是就抛出异常要求返回Task的目的是为了后续包装RequestDelegateif (!typeof(Task).IsAssignableFrom(methodInfo.ReturnType)){throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNonTaskReturnType(InvokeMethodName, InvokeAsyncMethodName, nameof(Task)));}// 判断方法的参数参数的第一个参数必须是HttpContext类型var parameters methodInfo.GetParameters();if (parameters.Length 0 || parameters[0].ParameterType ! typeof(HttpContext)){throw new InvalidOperationException(Resources.FormatException_UseMiddlewareNoParameters(InvokeMethodName, InvokeAsyncMethodName, nameof(HttpContext)));}// 开始构造RequestDelegate对象var ctorArgs new object[args.Length 1];ctorArgs[0] next;Array.Copy(args, 0, ctorArgs, 1, args.Length);var instance ActivatorUtilities.CreateInstance(app.ApplicationServices, middleware, ctorArgs);// 如果参数只有一个HttpContext 就包装成一个RequestDelegate返回if (parameters.Length 1){return (RequestDelegate)methodInfo.CreateDelegate(typeof(RequestDelegate), instance);}// 如果参数有多个的情况就单独处理这里不详细进去了var factory Compileobject(methodInfo, parameters);return context {var serviceProvider context.RequestServices ?? applicationServices;if (serviceProvider null){throw new InvalidOperationException(Resources.FormatException_UseMiddlewareIServiceProviderNotAvailable(nameof(IServiceProvider)));}return factory(instance, context, serviceProvider);};}); } 以上代码其实现在拿出来有点早了以上是对自定义中间件的注册方式为了扒代码的逻辑完整拿出来了这里可以不用深究里面内容知道内部调用了IApplicationBuilder的Use方法即可由此可见IApplicationBuilder就是构造请求管道的核心类型如下namespace Microsoft.AspNetCore.Builder {public interface IApplicationBuilder{// 容器用于依赖注入获取对象的IServiceProvider ApplicationServices{get;set;}// 属性集合用于中间件共享数据IDictionarystring, object Properties{get;}// 针对服务器的特性IFeatureCollection ServerFeatures{get;}// 构建请求管道RequestDelegate Build();// 克隆实例的IApplicationBuilder New();// 注册中间件IApplicationBuilder Use(FuncRequestDelegate, RequestDelegate middleware);} } IApplicationBuilder的默认实现就是ApplicationBuilder走起一探究竟namespace Microsoft.AspNetCore.Builder { // 以下 删除一些属性和方法具体可以私下看具体代码public class ApplicationBuilder : IApplicationBuilder{// 存储注册中间件的链表private readonly IListFuncRequestDelegate, RequestDelegate _components  new ListFuncRequestDelegate, RequestDelegate();// 注册中间件public IApplicationBuilder Use(FuncRequestDelegate, RequestDelegate middleware){// 将中间件加入到链表_components.Add(middleware);return this;}// 构造请求管道public RequestDelegate Build(){// 构造一个404的中间件这就是为什么地址匹配不上时会报404的原因RequestDelegate app context {// 判断是否有Endpoint中间件var endpoint context.GetEndpoint();var endpointRequestDelegate endpoint?.RequestDelegate;if (endpointRequestDelegate ! null){var message $The request reached the end of the pipeline without executing the endpoint: {endpoint.DisplayName}. $Please register the EndpointMiddleware using {nameof(IApplicationBuilder)}.UseEndpoints(...) if using $routing.;throw new InvalidOperationException(message);}// 返回404 Codecontext.Response.StatusCode 404;return Task.CompletedTask;};// 构建管道首先将注册的链表倒序一把保证按照注册顺序执行foreach (var component in _components.Reverse()){app component(app);}// 最终返回return app;}} } 在注册的代码中可以看到所谓的中间件就是FuncRequestDelegate, RequestDelegate其中RequestDelegate就是一个委托用于处理请求的如下public delegate Task RequestDelegate(HttpContext context); 之所以用FuncRequestDelegate, RequestDelegate的形式表示中间件应该就是为了中间件间驱动方便毕竟中间件不是单独存在的是需要多个中间件结合使用的那请求管道构造完成了那请求是如何到管道中呢应该都知道Asp.NetCore内置了IServer负责监听对应的请求当请求过来时会将请求给IHttpApplicationTContext进行处理简单看一下接口定义namespace Microsoft.AspNetCore.Hosting.Server {public interface IHttpApplicationTContext {// 执行上下文创建TContext CreateContext(IFeatureCollection contextFeatures);// 执行上下文释放void DisposeContext(TContext context, Exception exception);// 处理请求这里就使用了请求管道处理Task ProcessRequestAsync(TContext context);} } 而对于IHttpApplicationTContext类型来说默认创建的就是HostingApplication如下namespace Microsoft.AspNetCore.Hosting {internal class HostingApplication : IHttpApplicationHostingApplication.Context{// 构建出来的请求管道private readonly RequestDelegate _application;// 用于创建请求上下文的private readonly IHttpContextFactory _httpContextFactory;private readonly DefaultHttpContextFactory _defaultHttpContextFactory;private HostingApplicationDiagnostics _diagnostics;// 构造函数初始化变量public HostingApplication(RequestDelegate application,ILogger logger,DiagnosticListener diagnosticSource,IHttpContextFactory httpContextFactory){_application application;_diagnostics new HostingApplicationDiagnostics(logger, diagnosticSource);if (httpContextFactory is DefaultHttpContextFactory factory){_defaultHttpContextFactory factory;}else{_httpContextFactory httpContextFactory;}}// 创建对应的请求的上下文public Context CreateContext(IFeatureCollection contextFeatures){Context hostContext;if (contextFeatures is IHostContextContainerContext container){hostContext container.HostContext;if (hostContext is null){hostContext new Context();container.HostContext hostContext;}}else{// Server doesnt support pooling, so create a new ContexthostContext new Context();}HttpContext httpContext;if (_defaultHttpContextFactory ! null){var defaultHttpContext (DefaultHttpContext)hostContext.HttpContext;if (defaultHttpContext is null){httpContext _defaultHttpContextFactory.Create(contextFeatures);hostContext.HttpContext httpContext;}else{_defaultHttpContextFactory.Initialize(defaultHttpContext, contextFeatures);httpContext defaultHttpContext;}}else{httpContext _httpContextFactory.Create(contextFeatures);hostContext.HttpContext httpContext;}_diagnostics.BeginRequest(httpContext, hostContext);return hostContext;}// 将创建出来的请求上下文交给请求管道处理public Task ProcessRequestAsync(Context context){// 请求管道处理return _application(context.HttpContext);}// 以下删除了一些代码具体可下面查看....} } 这里关于Server监听到请求及将请求交给中间处理的具体过程没有具体描述可以结合启动流程和以上内容在细扒一下流程吧(大家私下搞吧)这里就简单说说中间件及请求管道构建的过程(后续有时间将整体流程走一遍)总结这节又是纯代码来“忽悠”小伙伴了对于理论概念可能表达的不够清楚欢迎交流沟通其实这里只是根据流程走了一遍源码并没有一行行解读所以小伙伴看此篇文章代码部分的时候以调试的思路去看从注册中间件那块开始到最后请求交给请求管道处理注重这个流程即可下一节说说中间件的具体应用------------------------------------------------一个被程序搞丑的帅小伙关注Code综艺圈识别关注跟我一起学~~~
http://www.pierceye.com/news/284260/

相关文章:

  • 太原做网站找谁阳江公司做网站
  • 企业网站aspwordpress原生相册
  • 重庆网站建设哪家公司那家好企业宣传软文
  • 如何选择营销网站建设什么网站做优化最好?
  • 个人博客网站模板素材网站的运营方案
  • wordpress增加网站网页关键词jquery验证网站地址
  • 企业招聘网站模板网站页面设计需要遵循的六大原则
  • 网站界面设计说明关键词排名顾问
  • 滨江区网站开发公司贵阳住房和城乡建设局网站
  • 如何建设小网站邢台市天气预报15天
  • 网站收录量低怎么做舟山公司网站制作
  • 部队网站模板计算机网站建设员
  • 对象储存做网站微博内网站怎么做的
  • 运城做网站要多少钱谷歌网站英文
  • 校园网站建设的意见与建议做儿童交互网站
  • 7黄页网站建设网站建设培训会讲话
  • 百度推广公司地址苏州优化方式
  • 做一个电商网站建设银行网站打不开用什么浏览器
  • 保定住房和城乡建设局网站沙洋网站定制
  • 北京电脑培训网站网站首页怎么做全屏swf
  • 网站建设 设计 优化 维护爱站网关键词挖掘工具
  • 做电影收费网站二级域名查询
  • 销售网站模板a5站长网网站交易
  • 网站需要怎么做的吗做营销网站那个好
  • 苏州网站建设软件收费广东网站设计哪家专业
  • 中国产品网免费网站网站自定义功能实现
  • 做微信小程序和做网站短视频素材下载网站
  • 自治区住房和城乡建设厅网站自己怎么健网站视频教程
  • 昆明建站网址dw怎么做秋季运动会网站
  • 为什么要建设个人网站在建工程