zoukankan      html  css  js  c++  java
  • ASP.Net Core管道和注册中间件精简版

    本文实现旨在实现ASP.Net Core管道和注册中间件的一个精简版。直接上代码。

    1、添加 WebHostBuilder 类。 

    public class WebHostBuilder
    
        {
    
            private HttpListenerServer _httpListener;
    
            private readonly List<Action<ApplicationBuilder>> _configures = new List<Action<ApplicationBuilder>>();
    
            public WebHost Build()
    
            {
    
                var builder = new ApplicationBuilder();
    
                foreach (var item in _configures)
    
                {
    
                    item(builder);
    
                }
    
                return new WebHost(_httpListener, builder.Build());
    
            }
    
            public WebHostBuilder Configure(Action<ApplicationBuilder> configure)
    
            {
    
                _configures.Add(configure);
    
                return this;
    
            }
    
            public WebHostBuilder UseServer(HttpListenerServer server)
    
            {
    
                _httpListener = server;
    
                return this;
    
            }
    
        } 

    2、添加 WebHost 类。

    public class WebHost
        {
            private readonly HttpListenerServer _httpListener;
            private readonly RequestDelegate _requestDelegate;
    
            public WebHost(HttpListenerServer server, RequestDelegate requestDelegate)
            {
                _httpListener = server;
                _requestDelegate = requestDelegate;
            }
            public Task StartAsync()
                => _httpListener.StartAsync(_requestDelegate);
        }

    3、添加 HttpListenerServer 类。

    public class HttpListenerServer
       {
           private readonly HttpListener _httpListener;// System.Net命名空间下
           private readonly string[] _urls;
    
           public HttpListenerServer(params string[] urls)
           {
               _httpListener = new HttpListener();
               _urls = urls.Any() ? urls : new string[] { "http://localhost:5007/", "http://127.0.0.1:5007/" };
           }
    
           public async Task StartAsync(RequestDelegate handler)
           {
               Array.ForEach(_urls, url => _httpListener.Prefixes.Add(url));
               _httpListener.Start();
               while (true)
               {
                   HttpListenerContext listenerContext = await _httpListener.GetContextAsync();// System.Net命名空间下
                   HttpRequest httpRequest = new HttpRequest();
                   httpRequest.Url = listenerContext.Request.Url;
                   httpRequest.Headers = listenerContext.Request.Headers;
                   httpRequest.Body = listenerContext.Request.InputStream;
    
                   HttpResponse httpResponse = new HttpResponse(listenerContext);
                   httpResponse.Headers = listenerContext.Response.Headers;
                   httpResponse.StatusCode = listenerContext.Response.StatusCode;
    
                   var httpContext = new HttpContext(httpRequest, httpResponse);
                   await handler(httpContext);
                   listenerContext.Response.Close();
               }
           }
       } 

    4、添加 ApplicationBuilder 类。

    public class ApplicationBuilder
       {
           private readonly List<Func<RequestDelegate, RequestDelegate>> _middlewares = new List<Func<RequestDelegate, RequestDelegate>>();
    
           public RequestDelegate Build()
           {
               _middlewares.Reverse();
               return httpContext =>
               {
                   RequestDelegate next = _ =>
                   {
                       _.Response.StatusCode = 404;
                       _.Response.ContentType = "text/plain;charset=utf-8";
                       _.Response.WriteAsync("您访问的页面逃走了");
                       return Task.CompletedTask;
                   };
                   foreach (var item in _middlewares)
                   {
                       next = item(next);
                   }
                   return next(httpContext);
               };
           }
    
           public ApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
           {
               _middlewares.Add(middleware);
               return this;
           }
    
       }

    5、添加 RequestDelegate 类。

    public delegate Task RequestDelegate(HttpContext httpContext);

    6、添加 HttpContext 类。 

    public class HttpContext
      {
          public HttpRequest Request { get; }
    
          public HttpResponse Response { get; }
    
          public HttpContext(HttpRequest httpRequest, HttpResponse httpResponse)
          {
              Request = httpRequest;
              Response = httpResponse;
          }
    
      } 

    7、添加 HttpRequest 类。 

    public class HttpRequest 
     {       
           public Uri Url { get; set; }  
           public NameValueCollection Headers { get; set; }    
           public Stream Body { get; set; }  
     } 

    8、添加 HttpResponse 类。 

    public class HttpResponse
        {
            private HttpListenerContext httpListener;// System.Net命名空间下
            public HttpResponse(HttpListenerContext listenerContext)
            {
                httpListener = listenerContext;
            }
            public NameValueCollection Headers { get; set; }
            public Stream Body
            {
                get
                {
                    return httpListener.Response.OutputStream;
                }
            }
            public int StatusCode { get; set; }
    
            public string ContentType {
                get
                {
                    return httpListener.Response.ContentType;
    
                }
                set
                {
                    httpListener.Response.ContentType = value;
                }
            }
    
        } 

    9、添加扩展方法 ExtensionMethod 。

    public static class ExtensionMethod
      {
          public static Task WriteAsync(this HttpResponse response, string contents)
          {
              var buffer = Encoding.UTF8.GetBytes(contents);
              return response.Body.WriteAsync(buffer, 0, buffer.Length);
          }
      } 

    10、新建一个控制台项目测试。 

    class Program
       {
           static async Task Main(string[] args)
           {
               await new WebHostBuilder()
                   .UseServer(new HttpListenerServer(@"http://localhost:5003/"))
                   //.Configure(app => { })
                   .Configure(app =>
                   app.Use(F1)
                   .Use(F2)
                   .Use(F3))
                   .Build()
                   .StartAsync();
           }
           public static RequestDelegate F1(RequestDelegate requestDelegate)
           {
               return context =>
               {
                   context.Response.ContentType = "text/plain;charset=utf-8";
                   context.Response.WriteAsync("访问F1");
                   return requestDelegate(context);
               };
           }
    
           public static RequestDelegate F2(RequestDelegate requestDelegate)
           {
               return context =>
               {
                   context.Response.ContentType = "text/plain;charset=utf-8";
                   context.Response.WriteAsync("访问F2");
                   return requestDelegate(context);
               };
           }
    
           public static RequestDelegate F3(RequestDelegate requestDelegate)
           {
               return async context =>
               {
                   context.Response.ContentType = "text/plain;charset=utf-8";
                   await context.Response.WriteAsync("访问F3");
               };
           }
       } 

    11、本文所建项目都是使用 .Net 5.0 框架 。

  • 相关阅读:
    python3删除mysql上月分区数据(脚本)
    ansible之基本原理及命令
    centOS 7 简单设置(虚拟机)
    TCP_Wrappers 简介
    sudo
    引用数据应该选择 ID, CODE 还是 NAME
    吃得洒脱是一种什么体验
    通用数据同步机制
    我的学PyTorch之路(1)
    38岁才学会了游泳的心得
  • 原文地址:https://www.cnblogs.com/lhwpc/p/15013862.html
Copyright © 2011-2022 走看看