Web 主机和中间件

以下内容为 奕鼎通教育  YDT9974 的课程学习笔记整理,特此感谢

Web主机使用

使用Web主机

    internal class Program
    {
        static void Main(string[] args)
        {
            #region 1、web主机使用
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);
                // 2、创建WebApplication
                var app = webApplication.Build();

                // 3、运行项目
                app.Run();
            }
            #endregion
        }
    }

Web主机使用-端口监听

        static void Main(string[] args)
        {
            #region 2、web主机使用-端口监听
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);
                // 2、创建WebApplication
                var app = webApplication.Build();

                app.Run("http://localhost:5008");
            }
            #endregion
        }

Web主机使用-多端口监听

        static void Main(string[] args)
        {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);
                // 2、创建WebApplication
                var app = webApplication.Build();

                // 3、运行项目
                app.Urls.Add("http://localhost:5008");
                app.Urls.Add("https://localhost:5009");
                app.Run();

        }

几种主机的使用

webApplication.WebHost.UseKestrel();
webApplication.WebHost.UseIIS();
webApplication.WebHost.UseHttpSys();
方法名服务器类型适用场景特点是否跨平台性能备注
UseKestrel()Kestrel默认推荐,适用于大多数场景轻量、高性能、跨平台✅ 是⭐⭐⭐⭐通常用于生产环境,支持反向代理(如 Nginx)
UseIIS()IIS(Internet Information Services)Windows 环境下与 IIS 集成支持 Windows 身份验证、集成托管❌ 否⭐⭐⭐需要 IIS 支持,适合企业内部部署
UseHttpSys()Http.Sys(Windows 内核 HTTP 服务器)Windows 环境下无需 IIS 的独立部署支持 Windows 身份验证、HTTPS、请求队列❌ 否⭐⭐⭐适合需要高级 Windows 功能的场景,如 Windows 身份验证

Web主机使用-外网访问

        static void Main(string[] args)
        {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // 3、运行项目
                app.Run("http://+:5009");
        }

中间件使用

技术:Microsoft.AspNetCore.Http

响应字符串

        static void Main(string[] args)
        {
            #region 2、中间件使用-响应字符串
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // 4、使用中间件响应ResposeString
                app.Run(async context =>
                {
                    await ResposeString(context);
                });

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
        
        public static async Task ResposeString(HttpContext httpContext)
        {
            // 1、响应字符串
           await httpContext.Response.WriteAsync("Hello World");
        }   

响应对象

        static void Main(string[] args)
        {
            #region 2.2、中间件使用-响应对象
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // 4、使用中间件响应ResposeString
                app.Run(async context =>
                {
                    await ResposeObject(context);
                });

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
        
        public static async Task ResposeObject(HttpContext httpContext)
         {
             // 1、响应对象
             Student student = new Student();
             student.Id = 1;
             student.Name = "云淡风清";
             await httpContext.Response.WriteAsJsonAsync(student);
         }

响应集合对象

        static void Main(string[] args)
        {
            #region 2.2、中间件使用-响应集合对象
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // 4、使用中间件响应ResposeString
                app.Run(async context =>
                {
                    await ResposeListObject(context);
                });

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
        
       public static async Task ResposeListObject(HttpContext httpContext)
        {
                // 1、响应集合对象
                List<Student> students = new List<Student>();
                students.Add(new Student() { 
                    Id = 1,
                    Name="帅仔"
                });
                students.Add(new Student()
                {
                    Id = 2,
                    Name = "keke"
                });
                students.Add(new Student()
                {
                    Id = 3,
                    Name = "张培武"
                });
                await httpContext.Response.WriteAsJsonAsync(students);
        }

响应Html

        static void Main(string[] args)
        {
            #region 2.3、中间件使用-响应Html
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // 4、使用中间件响应ResposeString
                app.Run(async context =>
                {
                    await ResposeHtml(context);
                });

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
        
       public static async Task ResposeHtml(HttpContext httpContext)
        {
            // 1、设置内容类型
            httpContext.Response.ContentType = "text/html";
            // 2、获取html文件路径
            var filepath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html");
            // 3、读取文件内容
            var htmlContent = await File.ReadAllTextAsync(filepath);
            // 4、响应输出
            await httpContext.Response.WriteAsync(htmlContent);
        }
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    hello world 兄弟们!
</body>
</html>

响应动态

        static void Main(string[] args)
        {
            #region 2.6、中间件链-不同请求,响应不同资源
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // RequestDelegate 创建当前的中间件 RequestDelegate 下一个中间件
                // 1、响应Html中间件
                app.Use(async (context, next) =>
                {
                    // 1、获取请求路径 /js  /html /css /
                    var path = context.Request.Path.Value;
                    if (path.Equals("/html"))
                    {
                        await ResposeHtml(context);
                    }
                    else
                    {
                        // 2、给下一个中间件
                        await next();
                    }
                });

               

                // 4、响应集合对象
                app.Use(async (context, next) =>
                {
                    // 1、获取请求路径 /js  /html /css /
                    var path = context.Request.Path.Value;
                    if (path.Equals("/"))
                    {
                        await ResposeListObject(context);
                    }
                    else
                    {
                        // 2、给下一个中间件
                        await next();
                    }
                });

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
        
        public static async Task ResposeHtml(HttpContext httpContext)
        {
            // 1、设置内容类型
            httpContext.Response.ContentType = "text/html";
            // 2、获取html文件路径
            var filepath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html");
            // 3、读取文件内容
            var htmlContent = await File.ReadAllTextAsync(filepath);
            // 4、响应输出
            await httpContext.Response.WriteAsync(htmlContent);
        }
        

        public static async Task ResposeListObject(HttpContext httpContext)
        {
            // 1、响应集合对象
            List<Student> students = new List<Student>();
            students.Add(new Student() { 
                Id = 1,
                Name="帅仔"
            });
            students.Add(new Student()
            {
                Id = 2,
                Name = "keke"
            });
            students.Add(new Student()
            {
                Id = 3,
                Name = "张培武"
            });
            await httpContext.Response.WriteAsJsonAsync(students);
        }

中间件链

中间件是一个组件,用于处理 HTTP 请求和响应。ASP.NET Core 使用一组中间件组成一个“管道”,每个中间件可以:

  • 处理请求
  • 修改请求或响应
  • 决定是否将请求传递给下一个中间件

这个链条就是所谓的 中间件管道(Middleware Pipeline)

中间件链的执行流程

  1. 请求进入应用程序
  2. 依次通过中间件链
    • 每个中间件可以选择:
      • 处理请求并终止链条(例如返回响应)
      • 或调用 next() 把请求传递给下一个中间件
  3. 最后一个中间件处理完后,响应开始返回
  4. 响应依次回传经过每个中间件
    • 每个中间件可以在响应返回时做一些处理(例如添加响应头)

中间件的作用

中间件可以实现各种功能,例如:

  • 认证与授权(Authentication & Authorization)
  • 日志记录(Logging)
  • 异常处理(Exception Handling)
  • 请求重定向
  • 静态文件处理
  • 跨域处理(CORS)
  • 自定义业务逻辑

定义一个中间件

你可以使用 app.Useapp.Run 或自定义类来定义中间件

中间件封装

    /// <summary>
    /// Html中间件
    /// </summary>
    public class HtmlMiddlewares
    {
        /// <summary>
        /// 下一个中间件
        /// </summary>
        private RequestDelegate next;
        public HtmlMiddlewares(RequestDelegate next)
        {
            this.next = next;
        }

        /// <summary>
        ///  1、处理请求
        ///  2、响应请求
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context) 
        {
            // 1、获取请求路径 /js  /html /css /
            var path = context.Request.Path.Value;
            if (path.Equals("/html"))
            {
                await ResposeHtml(context);
            }
            else
            {
                // 2、给下一个中间件
                await next(context);
            }
        }
        public static async Task ResposeHtml(HttpContext httpContext)
        {
            // 1、设置内容类型
            httpContext.Response.ContentType = "text/html";
            // 2、获取html文件路径
            var filepath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html");
            // 3、读取文件内容
            var htmlContent = await File.ReadAllTextAsync(filepath);
            // 4、响应输出
            await httpContext.Response.WriteAsync(htmlContent);
        }
    }
    /// <summary>
    /// ListObject中间件
    /// </summary>
    public class ListObjectMiddlewares
    {
        /// <summary>
        /// 下一个中间件
        /// </summary>
        private RequestDelegate next;
        public ListObjectMiddlewares(RequestDelegate next)
        {
            this.next = next;
        }

        /// <summary>
        ///  1、处理请求
        ///  2、响应请求
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context) 
        {
            // 1、获取请求路径 /js  /html /css /
            var path = context.Request.Path.Value;
            if (path.Equals("/"))
            {
                await ResposeListObject(context);
            }
            else
            {
                // 2、给下一个中间件
                await next(context);
            }
        }
        public static async Task ResposeListObject(HttpContext httpContext)
        {
            // 1、响应集合对象
            List<Student> students = new List<Student>();
            students.Add(new Student()
            {
                Id = 1,
                Name = "帅仔"
            });
            students.Add(new Student()
            {
                Id = 2,
                Name = "keke"
            });
            students.Add(new Student()
            {
                Id = 3,
                Name = "张培武"
            });

            throw new Exception("集合对象查询异常");
            await httpContext.Response.WriteAsJsonAsync(students);
        }
    }

使用中间件

    internal class Program
    {
        static void Main(string[] args)
        {
            #region 2.6、中间件链-封装
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // RequestDelegate 创建当前的中间件 RequestDelegate 下一个中间件
                // 1、响应Html中间件
                app.UseMiddleware<HtmlMiddlewares>();

                app.UseMiddleware<ListObjectMiddlewares>();

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
    }

中间件扩展

扩展是在封装的基础上

    /// <summary>
    /// html中间件扩展
    /// </summary>
    public static class HtmlMiddlewaresExtensions { 
        public static IApplicationBuilder UseHtml(this IApplicationBuilder app)
        {
            app.UseMiddleware<HtmlMiddlewares>();
            return app;
        }
    }
    /// <summary>
    /// ListObject中间件扩展
    /// </summary>
    public static class ListObjectMiddlewaresExtensions
    {
        public static IApplicationBuilder UseListObject(this IApplicationBuilder app)
        {
            app.UseMiddleware<ListObjectMiddlewares>();
            return app;
        }
    }

使用中间件

    internal class Program
    {
        static void Main(string[] args)
        {
            #region 2.7、中间件链-封装扩展
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // RequestDelegate 创建当前的中间件 RequestDelegate 下一个中间件
                // 1、响应Html中间件
                app.UseHtml();
               
                app.UseListObject();

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
    }

类的之间关系

类之间的关系

  1. HtmlMiddlewares 类

    • 是一个自定义中间件类,负责处理特定路径(如 /html)的请求。
    • 构造函数接收一个 RequestDelegate 类型的参数 next,表示下一个中间件。
    • 方法 InvokeAsync(HttpContext context) 是中间件的核心逻辑。
  2. HtmlMiddlewaresExtensions 类

    • 是一个静态扩展类,提供了 UseHtml() 方法,用于将 HtmlMiddlewares 添加到中间件管道中。
    • 使用了 ASP.NET Core 的扩展机制(IApplicationBuilder 的扩展方法)。
  3. Program 类

    • 是应用程序的入口点,负责构建和运行 Web 应用。
    • 在 Main 方法中调用 app.UseHtml() 来注册中间件。

📦 封装(Encapsulation)

封装是面向对象编程的核心思想之一,指的是将数据和行为封装在类中,隐藏内部实现细节,只暴露必要的接口。

在这段代码中:

  • HtmlMiddlewares 封装了处理 /html 请求的逻辑:
    • ResposeHtml() 方法封装了读取 HTML 文件并响应的过程。
    • InvokeAsync() 方法封装了请求路径判断和中间件链的调用。
  • HtmlMiddlewaresExtensions 封装了中间件注册的逻辑,使得使用者只需调用 UseHtml(),无需关心中间件的具体实现。

这种封装提高了代码的可读性可维护性复用性


🧩 扩展(Extension)

扩展是指在不修改原有类的情况下,为其添加新的功能。

在这段代码中:

  • HtmlMiddlewaresExtensions 使用了 C# 的扩展方法机制:

    这使得我们可以像使用框架内置中间件一样,调用 app.UseHtml() 来注册自定义中间件。
  • 这种方式符合 ASP.NET Core 的中间件设计模式,鼓励开发者通过扩展方法来组织和注册中间件。

中间件应用

    /// <summary>
    /// 商品模型
    /// </summary>
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    /// <summary>
    /// 商品service
    /// </summary>
    public class ProductService
    {
        public Product GetProduct()
        {
            //1、查询商品,抛出异常
            throw new Exception("查询商品异常");
            return new Product();   
        }
    }

封装对象

/// <summary>
/// 异常中间件,统一处理所有的异常
/// </summary>
public class ExceptionMiddlewares
{
    /// <summary>
    /// 下一个中间件
    /// </summary>
    private RequestDelegate next;
    private ProductService productService;
    public ExceptionMiddlewares(RequestDelegate next,
                                ProductService productService)
    {
        this.next = next;
        this.productService = productService;
    }

    /// <summary>
    /// 统一处理异常
    ///  1、处理请求
    ///  2、响应请求
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task InvokeAsync(HttpContext context) 
    {
        try
        {
            // 1、获取请求路径 /js  /html /css /
            var path = context.Request.Path.Value;
            if (path.Equals("/GetProduct"))
            {
                productService.GetProduct();
            }
            else
            {
                // 2、给下一个中间件
                await next(context);
            }
        }
        catch (Exception e)
        {
            // 统一处理异常
            // 1、包装异常
            var exceptioResponse = new
            {
                Code = "EX0001",
                Message = e.Message
            };

            // 2、输出异常
            await context.Response.WriteAsJsonAsync(exceptioResponse);    
        }
    }
}

扩展静态类

/// <summary>
/// 异常中间件扩展
/// </summary>
public static class ExceptionMiddlewaresExtensions
{
    public static IApplicationBuilder UseException(this IApplicationBuilder app)
    {
        app.UseMiddleware<ExceptionMiddlewares>();
        return app;
    }
}

使用

    internal class Program
    {
        static void Main(string[] args)
        {
            #region 2.8、中间件链-应用
            {
                // 1、创建WebApplicationBuilder
                var webApplication = WebApplication.CreateBuilder(args);
                // 1.1、注册ProductService
                webApplication.Services.AddSingleton<ProductService>();

                // 2、内置托管主机切换。默认:Kestrel IIS HttpSys
                webApplication.WebHost.UseKestrel();

                // 2、创建WebApplication
                var app = webApplication.Build();

                // RequestDelegate 创建当前的中间件 RequestDelegate 下一个中间件
                // 1、响应Exception中间件
                app.UseException();
                app.UseHtml();
                
                app.UseListObject();

                // 3、运行项目
                app.Run("http://+:5009");
            }
            #endregion
        }
    }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值