为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
C#

说到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 类型提供了很多重写和重定向的方法,除了上述的 AddRedirect , AddRewrite 外,还有两个比较好玩的方法.

1.Add(Action<RewriteContext> applyRule)

接收一个委托.当请求地址符合一个规则后,方法传递的委托便会执行.这里以修改 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); })  这句代码.

测试图如下:

 

可以看到,上面的请求不符合规则,页面上什么都没显示;下面的请求符合规则,页面显示出了重写后的请求路径. 

2.AddRedirectToHttps

该方法可以将 HTTP 请求重定向到采用 HTTPS 的相同主机和路径.

新建一个 WebAPI 项目,但是不勾选  "为HTTPS配置" 选项.

修改 Configure 方法. 

复制代码

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }            var options = new RewriteOptions();
            options.AddRedirectToHttps(statusCode: 301, sslPort: 9527);
            app.UseRewriter(options);
            app.UseMvc();
        }

复制代码

在浏览器地址栏输入该项目地址 : http://localhost:50588 ,会重定向到 https://localhost:9527 , 如图.

 

 

上面所有重写的示例中,重写的规则都是写在代码里面的,而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  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消