问题

如何在ASP.NET Core 2.0中实现网址重定向?

答案

新建一个空项目,在Startup.cs文件中,配置RewriteOptions参数并添加网址重定向中间件(UseRewriter):

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var rewrite = new RewriteOptions()
.AddRedirect("films", "movies")
.AddRewrite("actors", "stars", true); app.UseRewriter(rewrite); app.Run(async (context) =>
{
var path = context.Request.Path;
var query = context.Request.QueryString;
await context.Response.WriteAsync($"New URL: {path}{query}");
});
}  

运行,并在浏览器地址栏输入:http://localhost:56825/films,通过客户端调试工具观察重定向过程:

在地址栏输入:http://localhost:56825/actors,再次观察重定向过程:

讨论

网址重定向就是根据用户自定义规则来修改请求的网址,目的是为了将服务器资源和浏览器网址解绑定。这样做可能是出于安全考虑, 搜索引擎优化(SEO),用户友好网址,将HTTP重定向到HTTPS等多种目的。

当你无法使用Web服务器(IIS,Apache,Nginx)的重定向功能时,ASP.NET Core提供了一个可选项 - 请求网址重定向中间件。然后它的性能和功能比不上Web服务器的重定向。

重定向中间件可以做两件事情:客户端重定向和服务器重写:

重定向(客户端)

这是一个客户端操作,工作流程如下:

1. 客户端请求一个资源,比如 /films

2. 服务器返回301(Moved Permanently)或者302(Found)状态码,并在响应头中添加Location属性,用来指示浏览器请求新的地址(比如/movies)。

3. 客户端请求新的地址,并显示在浏览器的地址栏中。

重写(服务端)

它是一个服务器端操作,工作流程如下:

1. 客户端请求一个资源,比如 /actors

2. 服务器将其内部映射到新的地址(比如/stars)并且返回200(OK)。

在此过程中,客户端并不知道服务器端的内部映射操作,因此用户看到的浏览器地址栏依然显示的是最初请求地址。

规则

重定向和重写规则可以是正则表达式,更加详细的信息请参考:https://docs.microsoft.com/en-gb/aspnet/core/fundamentals/url-rewriting

自定义重定向规则

我们也可以自定义重定向规则,通过一个继承自IRule接口的类来实现:

public class MoviesRedirectRule : IRule
{
private readonly string[] _matchPaths;
private readonly string _newPath; public MoviesRedirectRule(string[] matchPaths, string newPath)
{
_matchPaths = matchPaths;
_newPath = newPath;
} public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request; // 已经是目标地址了,直接返回
if (request.Path.StartsWithSegments(new PathString(_newPath)))
{
return;
} if (_matchPaths.Contains(request.Path.Value))
{
var newLocation = $"{_newPath}{request.QueryString}"; var response = context.HttpContext.Response;
response.StatusCode = StatusCodes.Status302Found;
context.Result = RuleResult.EndResponse;
response.Headers[HeaderNames.Location] = newLocation;
}
}
}  

然后在Configure()中,将此自定义规则添加到RewriteOptions里面:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var rewrite = new RewriteOptions()
.Add(new MoviesRedirectRule(
matchPaths: new string[] { "/films", "/features", "/albums" },
newPath: "/movies")); app.UseRewriter(rewrite); app.Run(async (context) =>
{
var path = context.Request.Path;
var query = context.Request.QueryString;
await context.Response.WriteAsync($"New URL: {path}{query}");
});
}  

运行,在地址栏输入:http://localhost:56825/films?id=123,观察重定向过程:

源代码下载

原文:https://tahirnaushad.com/2017/08/18/url-rewriting-in-asp-net-core/

[译]ASP.NET Core 2.0 网址重定向的更多相关文章

  1. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  2. [译]ASP.NET Core 2.0 路由引擎之网址生成

    问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...

  3. [译]ASP.NET Core 2.0 中间件

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...

  4. [译]ASP.NET Core 2.0 带初始参数的中间件

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...

  5. [译]ASP.NET Core 2.0 全局配置项

    问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...

  6. [译]ASP.NET Core 2.0 机密配置项

    问题 如何在ASP.NET Core 2.0中保存机密配置项(不用将其暴露给源代码管理器)? 答案 创建一个ASP.NET Core 2.0空项目,在项目节点上点击右键,并点击菜单项 - 管理用户机密 ...

  7. [译]ASP.NET Core 2.0 会话状态

    问题 如何在ASP.NET Core 2.0中存储会话状态? 答案 创建一个空项目,修改Startup类的ConfigureServices()方法,添加会话状态服务和它后台的存储服务: public ...

  8. [译]ASP.NET Core 2.0 本地文件操作

    问题 如何在ASP.NET Core 2.0中受限地访问本地目录和文件信息? 答案 新建一个空项目,修改Startup类,添加访问本地文件所需的服务: public void ConfigureSer ...

  9. [译]ASP.NET Core 2.0 路由引擎

    问题 ASP.NET Core 2.0的路由引擎是如何工作的? 答案 创建一个空项目,为Startup类添加MVC服务和请求中间件: public void ConfigureServices(ISe ...

随机推荐

  1. Shiro初识与总结

    1.1简介 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动应用程序 ...

  2. 工作中对数组的一些处理,整理(结合underscore.js)

    1.数组里边相同元素提取成map,并以'',''分隔 例如:var arr = [{a:"xx",b:''xxx''},{a:"xxx",b:''xxxxx'' ...

  3. HTML 4.01+5基礎知識

    HTML 4.01+5 1.Html結構:html>head+body 2.Html快捷鍵:!加Tab(在sublime中) 3.雙標籤: ①常用標籤 h1.h2.h3.h4.h5.h6 p.c ...

  4. (转)Unity3D中移动物体位置的几种方法

    1. 简介 在unity3d中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position. 2. 通过Transform组件移动物体 Transform 组件用于描述物体在 ...

  5. axios 学习笔记

    官方文档地址:https://github.com/axios/axios axios 是一个基于 Promise 的HTTP库,可以用在浏览器和 node.js 中 特性: • 从浏览器发起 XML ...

  6. 关于select的一个错误---属性选择器

    错误: jquery 获取下拉框 text='1'的 option 的value 属性值  我写的var t= $("#selectID option[text='1']).val() ; ...

  7. Hive 存储类型 StoreType

    file_format: : SEQUENCEFILE | TEXTFILE -- (Default, depending on hive.default.fileformat configurati ...

  8. Android打包版本号设置

    之前没有设置过打包的命名,每次打包都是默认的"app-realease.apk",之后手动修改名字来显示出它是一个新版本. 晚上学习了如何配置打包名称,很简单,修改build.gr ...

  9. hud 2577 How to Type

    How to Type Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  10. BZOJ-5055-膜法师(离散化+树状数组)

    Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...