Remove additional slash from URL in Asp.Net Core

Viewed 1184

I have a web-site, hosted on Azure App Service. What I'd like to do is to redirect traffic, such that an address like:

https://mysitecom//test//test2

Or:

https://mysitecom/test//test2

Would redirect to the same location:

https://mysitecom/test/test2

So far, I've tried adding some middleware to deal with this; for example:

app.Use(next => context =>
{
    if (context.Request.Path.Value.Contains("//"))
    {            
        context.Response.Redirect(context.Request.Path.Value.Replace("//", "/"), true);
        return;
    }
});

I've also tried:

var options = new RewriteOptions()
    .AddRedirect("redirect-rule/^(.*)//(.*)$", "redirected/$1/%2");                                       

app.UseRewriter(options);

Both of these work locally to an extent; however, it appears that running under Kestrel the slashes are automatically reduced to a single one. When this is deployed to Azure App Service, the following happens:

  • The slashes remain (e.g. https://mysitecom//test//test2)
  • The correct page is located
  • The middleware sees only a single slash

Please can someone explain why the middleware (or the redirect) is only ever seeing a single slash when this is deployed to Azure?

(SO wouldn't allow me to use an actual URL in the post)

2 Answers

If your site runs on a Windows AppService, it runs in IIS. You are encountering an IIS feature (The "URL Rewrite Module", I think). If you run the same site on Linux, it will behave differently.

If you want to detect the "original" URL, you can try something like this:

// => /test/test2
var path1 = Request.Path

// => //test//test2
var path2 = HttpContext.Features.Get<IServerVariablesFeature>()["UNENCODED_URL"]

There are multiple sources for this behavior, though I am not sure how you could turn it off if you wanted to.

It should work in .NET Core

var options = new RewriteOptions()
    .AddRedirect("(.*)/$", "$1", 301 /* Moved Permanently */);
app.UseRewriter(options);
Related