Asp.net 核心 url 从中间件重写不工作
Asp.net core url re-writing from middleware not working
我有一个带有一些 mvc 控制器和一个 angular 2 应用程序的点网核心 Web 应用程序。我正在尝试将 "www.example.com/old/path" 之类的请求路径重写为 "www.example.com/new/path",然后将其发送到 angular 2 应用程序(仅针对 "new/path" 设置路由)。但是 Angular 一直在使用旧路径,即使重写似乎有效(从断点判断)。我怀疑这可能反映了我对中间件执行顺序的理解存在某种差距(但我尝试了不同的顺序并在各处发送重写代码无济于事)。
这是 url 重写中间件的样子 (UrlRewritingMiddleware.cs):
public sealed class UrlRewritingMiddleware
{
private readonly RequestDelegate _next;
private readonly string OldPathSegment= "/old/path/";
private readonly string NewPathSegment= "/new/path/";
public UrlRewritingMiddleware(RequestDelegate next)
{
this._next = next;
}
private void RewriteUrl(HttpContext context)
{
if (context.Request.Path.Value.IndexOf(OldPathSegment, 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
context.Request.Path = new PathString(Regex.Replace(context.Request.Path.Value, OldPathSegment, NewPathSegment, RegexOptions.IgnoreCase));
}
}
public async Task Invoke(HttpContext context)
{
RewriteUrl(context);
await _next.Invoke(context);
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/app/root/index.html";
context.Response.StatusCode = 200;
await _next.Invoke(context);
RewritePathsInContext(context);//spam
}
else
{
//spam
RewritePathsInContext(context);
}
}
}
然后这就是 Startup.cs 配置方法的样子:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//putting in the beginning, I get error in angular
//EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: '/old/path'
app.UseUrlRewritingMiddleware();
app.AnotherCustomMiddleware();//I can see Path changed to new/path inside here
app.UseDefaultFiles();
app.UseMvc();
app.UseStaticFiles();
//putting this at the end gives me 404 in asp.net
//app.UseUrlRewritingMiddleware();
}
睡了一觉后,我意识到服务器端重写请求路径不会改变浏览器中显示的 url(这是 angular 得到的) .所以 www.example.com/old/path 将在浏览器中保持不变,只有重定向才能将其更改为 www.example.com/new/path (这不是我想要的)。为了解决这个问题,我不得不在 angular 应用程序本身中添加重定向。我的 angular 应用程序还调用了一些 mvc 控制器/视图,但它们始终采用 /new/path 格式,因此此时我不需要服务器端重写。
另外,关于中间件的顺序我怀疑把它放在最后的原因在 asp.net 中给了我一个 404 可能是因为它在 UseMvc 中间件之后(它已经设置好了路线?)。尚未对其进行测试,但只要它出现在 UseMvc 中间件之前,我认为它应该可以工作。 编辑: 请参阅下面 ssmith 的评论。 UseMvc 是一个终端中间件,所以它之后的任何东西都不起作用。
如果您确实需要服务器端 url 重写,asp.net 核心有一个您可以使用的 re-writing middleware,实际上不需要自己编写:
var options = new RewriteOptions()
.AddRewrite(@"/old/path/", "/new/path/", skipRemainingRules: true);
app.UseRewriter(options);
我有一个带有一些 mvc 控制器和一个 angular 2 应用程序的点网核心 Web 应用程序。我正在尝试将 "www.example.com/old/path" 之类的请求路径重写为 "www.example.com/new/path",然后将其发送到 angular 2 应用程序(仅针对 "new/path" 设置路由)。但是 Angular 一直在使用旧路径,即使重写似乎有效(从断点判断)。我怀疑这可能反映了我对中间件执行顺序的理解存在某种差距(但我尝试了不同的顺序并在各处发送重写代码无济于事)。
这是 url 重写中间件的样子 (UrlRewritingMiddleware.cs):
public sealed class UrlRewritingMiddleware
{
private readonly RequestDelegate _next;
private readonly string OldPathSegment= "/old/path/";
private readonly string NewPathSegment= "/new/path/";
public UrlRewritingMiddleware(RequestDelegate next)
{
this._next = next;
}
private void RewriteUrl(HttpContext context)
{
if (context.Request.Path.Value.IndexOf(OldPathSegment, 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
context.Request.Path = new PathString(Regex.Replace(context.Request.Path.Value, OldPathSegment, NewPathSegment, RegexOptions.IgnoreCase));
}
}
public async Task Invoke(HttpContext context)
{
RewriteUrl(context);
await _next.Invoke(context);
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/app/root/index.html";
context.Response.StatusCode = 200;
await _next.Invoke(context);
RewritePathsInContext(context);//spam
}
else
{
//spam
RewritePathsInContext(context);
}
}
}
然后这就是 Startup.cs 配置方法的样子:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//putting in the beginning, I get error in angular
//EXCEPTION: Uncaught (in promise): Error: Cannot match any routes. URL Segment: '/old/path'
app.UseUrlRewritingMiddleware();
app.AnotherCustomMiddleware();//I can see Path changed to new/path inside here
app.UseDefaultFiles();
app.UseMvc();
app.UseStaticFiles();
//putting this at the end gives me 404 in asp.net
//app.UseUrlRewritingMiddleware();
}
睡了一觉后,我意识到服务器端重写请求路径不会改变浏览器中显示的 url(这是 angular 得到的) .所以 www.example.com/old/path 将在浏览器中保持不变,只有重定向才能将其更改为 www.example.com/new/path (这不是我想要的)。为了解决这个问题,我不得不在 angular 应用程序本身中添加重定向。我的 angular 应用程序还调用了一些 mvc 控制器/视图,但它们始终采用 /new/path 格式,因此此时我不需要服务器端重写。
另外,关于中间件的顺序我怀疑把它放在最后的原因在 asp.net 中给了我一个 404 可能是因为它在 UseMvc 中间件之后(它已经设置好了路线?)。尚未对其进行测试,但只要它出现在 UseMvc 中间件之前,我认为它应该可以工作。 编辑: 请参阅下面 ssmith 的评论。 UseMvc 是一个终端中间件,所以它之后的任何东西都不起作用。
如果您确实需要服务器端 url 重写,asp.net 核心有一个您可以使用的 re-writing middleware,实际上不需要自己编写:
var options = new RewriteOptions()
.AddRewrite(@"/old/path/", "/new/path/", skipRemainingRules: true);
app.UseRewriter(options);