ASP.NET Core 2.2 基础知识(四) URL重写中间件

说到URL重写就不得不提URL重定向.

URL重定向

URL重定向是客户端操作,指示客户端访问另一个地址的资源.这需要往返服务器,并且当客户端对资源发出请求时,返回客户端的重定向URL会出现在浏览器的地址栏中.

将请求重定向到不同的URL时,可指示重定向是永久的还是临时的.如果是永久的,则使用"301"状态码.收到"301"状态码时,客户端可能会缓存.如果是临时的,则使用"302"状态码,以使客户端将来不应存储和重用重定向URL.

示例:

新建一个WebAPI项目;新增一个 TestController 控制器;在 Startup 类的 Configure 方法中增加如下代码:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ...other codes
            var options = new RewriteOptions();
            //options.AddRedirect("^redirect/(.*)", "api/test");//默认状态码为 302
            options.AddRedirect("^redirect/(.*)", "api/test", 301);
            app.UseRewriter(options);

            app.Run(async context =>
                {
                    //注意重定向和重写URL两种情况下,浏览器地址栏和页面显示的 URL 的区别.
                    await context.Response.WriteAsync($"URL:{context.Request.Path + context.Request.QueryString}");
                });

            app.UseMvc();
        }

启动该项目,在浏览器地址栏输入 : https://localhost:44303/redirect/123 后,

可以看出,客户端一共请求了两次,浏览器地址栏变成了重定向的URL.

URL重写

URL重写是服务器端操作.重写URL不需要往返服务器,重写的URL也不会返回客户端,也不会出现在浏览器地址栏.

示例:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ...other codes

            var options = new RewriteOptions();
            options.AddRewrite("^rewrite/(.*)", "api/test", true);//重写URL,false/true 表示如果当前规则适用,是否跳过其他重写规则.
            app.UseRewriter(options);

            app.Run(async context =>
                {
                    //注意重定向和重写URL两种情况下,浏览器地址栏和页面显示的 URL 的区别.
                    await context.Response.WriteAsync($"URL:{context.Request.Path + context.Request.QueryString}");
                });

            app.UseMvc();
        }
    }

在浏览器地址栏输入 : https://localhost:44303/rewrite/1


RewriteOptions 类型提供了一个 Add 方法,接收一个委托.当请求地址符合一个规则后,方法传递的委托便会执行.这里以修改 reContext.Result 的值为例.示例:

            {
                RewriteOptions options = new RewriteOptions();
                options.AddRewrite("^rewrite*", "test", true).Add(reContext =>
                {
                    reContext.Result = RuleResult.EndResponse;
                });
                app.UseRewriter(options);
                app.Run(async context => { await context.Response.WriteAsync(context.Request.Path + context.Request.QueryString); });
            }

只有请求地址符合规则时才会执行  app.Run(async context => { await context.Response.WriteAsync(context.Request.Path + context.Request.QueryString); })  这句代码.

测试图如下:

可以看到,上面的请求不符合规则,页面上什么都没显示;

下面的请求符合规则,页面显示出了重写后的请求路径.

上面所有重写的示例中,重写的规则都是写在代码里面的,而ASP.NET Core 还提供了从文件中读取规则的方式.

新建一个文件夹 Rule ,添加一个 IISUrlRewrite.xml 文件,内容如下:

<rewrite>
  <rules>
    <rule name="MyIISUrlRewrite" stopProcessing="true">
      <match url="^rewrite/(.*)"/>
      <!--还 没发现 appendQueryString = false 和 true 的区别-->
      <action type="Rewrite" url="api/values/{R:1}" appendQueryString="false"/>
    </rule>
  </rules>
</rewrite>

修改 Configure 方法:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ......
            var options = new RewriteOptions();

            //方法一:
            //using (StreamReader sr = File.OpenText(Path.Combine(env.ContentRootPath, @"Rule\IISUrlRewrite.xml")))
            //{
            //    options.AddIISUrlRewrite(sr);
            //    app.UseRewriter(options);
            //}

            //方法二:
            var fileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Rule"));
            options.AddIISUrlRewrite(fileProvider, "IISUrlRewrite.xml");
            app.UseRewriter(options);

            app.Run(async context =>
                {
                    await context.Response.WriteAsync(context.Request.Path + context.Request.QueryString);
                });

            app.UseMvc();
        }

图就不上了.

虽然还没用 ASP.NET Core 开发过任何项目,但是我觉得下面这种重写和重定向的方法或许会是用得最多的,因为它足够灵活.

    public class MyRule : IRule
    {
        //可以自定义构造函数,做一些验证
        //public MyRule(string extension, string newPath)
        //{
        //    if (string.IsNullOrEmpty(extension))
        //    {
        //        throw new ArgumentException(nameof(extension));
        //    }
        //    if (!Regex.IsMatch(extension, @"^rewrite*"))
        //    {
        //        throw new ArgumentException("Invalid extension", nameof(extension));
        //    }
        //    if (!Regex.IsMatch(newPath, @"(/[A-Za-z0-9]+)+?"))
        //    {
        //        throw new ArgumentException("Invalid path", nameof(newPath));
        //    }

        //    _extension = extension;
        //    _newPath = new PathString(newPath);
        //}

        //private readonly string _extension;
        //private readonly PathString _newPath;

        private readonly string _extension;
        private readonly string _newPath;
        public MyRule(string extension, string newPath)
        {
            _extension = extension;
            _newPath = newPath;
        }

        public void ApplyRule(RewriteContext context)
        {
            HttpRequest request = context.HttpContext.Request;
            HttpResponse response = context.HttpContext.Response;

            //可以重写
            request.Path = new PathString(_newPath);
            context.Result = RuleResult.SkipRemainingRules;

            //可以重定向
            //if (request.Path.Value.EndsWith(_extension, StringComparison.OrdinalIgnoreCase))
            //{
            //    response.StatusCode = StatusCodes.Status302Found;
            //    context.Result = RuleResult.EndResponse;
            //    response.Headers[HeaderNames.Location] = _newPath;
            //}
        }
    }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            RewriteOptions options = new RewriteOptions();
            options.Add(new MyRule("rewrite","/api/test"));
            app.UseRewriter(options);

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }

原文地址:https://www.cnblogs.com/refuge/p/10213596.html

时间: 2024-10-27 02:45:31

ASP.NET Core 2.2 基础知识(四) URL重写中间件的相关文章

ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF)

原文:ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF) 先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn", "person": { "id": 1, "address": { "addName": "chengdu"

ASP.NET Core 2.2 基础知识(二) 中间件

原文:ASP.NET Core 2.2 基础知识(二) 中间件 中间件是一种装配到应用管道以处理请求和相应的软件.每个软件都可以: 1.选择是否将请求传递到管道中的下一个组件; 2.可在调用管道中的下一个组件前后执行工作. 管道由 IApplicationBuilder 创建: 每个委托都可以在下一个委托前后执行操作,.此外,委托还可以决定不将请求传递给下一个委托,这就是对请求管道进行短路.通常需要短路,是因为这样可以避免不必要的工作.比如: 1.静态文件中间件可以返回静态文件请求并使管道的其余

ASP.NET Core 2.2 基础知识(一) 依赖注入

原文:ASP.NET Core 2.2 基础知识(一) 依赖注入 依赖: 类A用到了类B,我们就说类A依赖类B.如果一个类没有任何地方使用到,那这个类基本上可以删掉了. public class Test { private MyDependency md = new MyDependency(); public void Print() { md.Print(); } } public class MyDependency { public void Print() { Console.Wri

ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块

原文:ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块 ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET Core 随附两种服务器实现: Kestrel 是适用于 ASP.NET Core 的默认跨平台 HTTP 服务器. HTTP.sys 是仅适用于 Windows 的 HTTP 服务器,它基于 HTTP.sy

ASP.NET Core 2.2 基础知识(五) 环境

原文:ASP.NET Core 2.2 基础知识(五) 环境 一.环境变量 系统启动时,会读取环境变量 ASPNETCORE_ENVIRONMENT ,并将该变量的值存储在 IHostingEnvironment.EnvironmentName 字段中.如: 新建一个 WebAPI 项目,修改 Configure 方法: public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ...... { app.R

ASP.NET Core 2.2 基础知识(十六) SignalR 概述

原文:ASP.NET Core 2.2 基础知识(十六) SignalR 概述 我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-2.2&tabs=visual-studio 这个例子一共涉及到下面几个步骤: 自定义中心 ChatH

ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)

要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person Get() { return new Person {Id = 1, Name = "refuge"}; } //控制器需要继承 Controller 类 public IActionResult Get() { return Ok("hello world"); }

ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如,可以注册 github 客户端,并将它配置为访问 GitHub. 可以注册一个默认客户端用于其他用途. 通过委托 HttpClient 中的处理程序整理出站中间件的概念,并提供适用于基于 Polly 的中间件的扩展来利用概念. 管理基础 HttpClientMessageHandler 实例的池和

ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述

为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择"发布": 我们依次选择"文件",设置好路径,最后点击创建配置文件,界面变成了下面这样: 然后我们点击"配置" 那么,问题来了."部署模式" 里面有两个选项: 1.当选择框架依赖时,"目标运行时"有:"可移植&