【问题标题】:Asp.net core url re-writing from middleware not working从中间件重写的 Asp.net 核心 url 不起作用
【发布时间】:2017-08-25 04:44:21
【问题描述】:

我有一个带有一些 mvc 控制器和一个 angular 2 应用程序的 dot net core web 应用程序。我正在尝试将“www.example.com/old/path”之类的请求路径重写为“www.example.com/new/path”,然后将其发送到 angular 2 应用程序(该应用程序的路由设置仅适用于“新/路径”)。但是,即使重写似乎已经奏效(从断点来看),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 Configure 方法的样子:

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

【问题讨论】:

    标签: c# angular asp.net-core asp.net-core-mvc asp.net-core-middleware


    【解决方案1】:

    睡了一夜好觉后,我意识到服务器端重写请求路径不会改变浏览器中显示的 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);
    

    【讨论】:

    • 如果你把中间件放在 UseMvc 之后,它就不会被命中。 MVC 正在终止。如果 MVC 没有找到任何东西,它会返回 404 而不是调用“下一个”中间件。
    • 这也可能对您有用(但对事物的角度方面没有帮助):ardalis.com/…
    • 啊,谢谢史密斯。这清除了一些事情:) 编辑答案以包含您提供的信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多