说到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();
}
}

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

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

    要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...

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

    为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择" ...

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

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

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

    先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn& ...

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

    我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microso ...

  6. ASP.NET Core 2.2 基础知识(十三) WebAPI 概述

    我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西 官方给出的模板: [Route("api/[controller]")] [ApiController] pub ...

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

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  8. ASP.NET Core 2.2 基础知识(十) Web服务器 - Kestrel

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  9. ASP.NET Core 2.2 基础知识(九) 使用托管服务实现后台任务

    在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法: StartAsync(CancellationT ...

随机推荐

  1. [Leetcode] palindrome partition ii 回文分区

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  2. CSS3边框会动的信封

    <!DOCTYPE html><html> <head> <title>酷炫的CSS3</title> <meta charset=& ...

  3. The XOR Largest Pair [Trie]

    描述 在给定的N个整数A1,A2--AN中选出两个进行xor运算,得到的结果最大是多少? 输入格式 第一行一个整数N,第二行N个整数A1-AN. 输出格式 一个整数表示答案. 样例输入 3 1 2 3 ...

  4. [fzu 2282]置换不动点大于等于k的排列数

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2282 编号1~n的置换,不动点个数大于等于k的方案数. 参考百度百科错排公式,可以知道长度为n,每个数都不在自 ...

  5. 继承spring的validator接口,实现对数据的校验

    在org.springframework.validation这个包中提供了一些对数据校验的方法,其中Validator接口是其中的一个. 现在用Validator接口,完成对数据的校验. 第一步:先 ...

  6. 用angular.element实现jquery的一些功能的简单示例

    下面实现了在每个p元素后面自动添加hello world. 在这里我要说的是jquery中的 $document.ready()相当于angualr 中的angualr.element(documen ...

  7. 栈与递归的实现(Hanoi塔问题等等)

    函数中有直接或间接地调用自身函数的语句,这样的函数称为递归函数.递归函数用 得好,可简化编程工作.但函数自己调用自己,有可能造成死循环.为了避免死循环,要 做到两点: (1) 降阶.递归函数虽然调用自 ...

  8. jquery序列化表单

    没有使用其他的东西 , 数据传送是最基本的. 前台: var info = $('#dataForm').serialize() ; alert(decodeURIComponent(info,tru ...

  9. [洛谷P1040] 加分二叉树

    洛谷题目链接:加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...

  10. HDU 2554 N对数的排列问题 ( 数学 )

    题目链接 Problem Description 有N对双胞胎,他们的年龄分别是1,2,3,--,N岁,他们手拉手排成一队到野外去玩,要经过一根独木桥,为了安全起见,要求年龄大的和年龄小的排在一起,好 ...