top of page

URL Rewriting Middleware in ASP.NET Core



URL rewriting is the act of modifying request URLs based on one or more predefined rules. URL rewriting creates an abstraction between resource locations and their addresses so that the locations and addresses aren't tightly linked. URL rewriting is valuable in several scenarios:

  • Move or replace server resources temporarily or permanently and maintain stable locators for those resources.

  • Split request processing across different apps or across areas of one app.

  • Remove, add, or reorganizing URL segments on incoming requests.

  • Optimize public URLs for Search Engine Optimization (SEO).

  • Permit the use of friendly public URLs to help visitors predict the content returned by requesting a resource.

  • Redirect insecure requests to secure endpoints.

  • Prevent hotlinking, where an external site uses a hosted static asset on another site by linking the asset into its own content.

URL rewriting can reduce the performance of an app. Limit the number and complexity of rules.


source: Microsoft


When to use URL rewriting middleware

Use URL Rewriting Middleware when the following approaches aren't satisfactory:

  • URL Rewrite module with IIS on Windows Server

  • Apache mod_rewrite module on Apache Server

  • URL rewriting on Nginx

Use the URL rewriting middleware when the app is hosted on HTTP.sys server.


The main reasons to use the server-based URL rewriting technologies in IIS, Apache, and Nginx are:

  • The middleware doesn't support the full features of these modules. Some of the features of the server modules don't work with ASP.NET Core projects, such as the IsFile and IsDirectory constraints of the IIS Rewrite module. In these scenarios, use the middleware instead.

  • The performance of the middleware probably doesn't match that of the modules. Benchmarking is the only way to know with certainty which approach degrades performance the most or if degraded performance is negligible.


URL Redirect vs URL Rewrite


URL Rewriting

Rewriting actually changes the current request's path internally and continues processing the current request with all of it's existing state through the middleware pipeline. Any middleware registered after the rewrite sees the new URL and processes the remainder of the request with the new path. All of this happens as a part single server request.

The URL of the request displayed in the address bar stays the same - the browser location doesn't change to the rewritten URL.


A rewrite can also keep request information, so if you have POST or PUT operation that has data associated with it, that data stays intact.

Uses context.Request.Path


URL Redirecting

Redirecting actually fires a new request on the server by triggering a new HTTP request in the browser via an 302 Moved or 301 Moved Permanently HTTP Response header that contains the redirection URL. A redirect is an HTTP header response to the client that instructs the client to: Redirects can also use 301 Moved Permanently to let search engines know that the old URL is deprecated and the new URL should be used instead.

Uses context.Response.Redirect()


A Redirect() on the other hand is always reissued as an HTTP GET operation by the browser so you can't redirect form input.


Intercepting URLS in ASP.NET Core

If you plan to intercept requests and rewrite them, the most likely place you'd want to do this is in ASP.NET Core is in Middleware. Rewrite components tend to look at incoming request paths or headers and determine whether they need to re-write the URL to something else.


If you want to do this in ASP.NET Core the easiest way to do this is to use app.Use() inline middleware which you can add to your Startup.Configure() method.


Re-Writing a URL

Here's how to handle a Rewrite operation in app.Use() middleware:

app.Use(async (context,next) =>
{
    var url = context.Request.Path.Value;

    // Rewrite to indexif (url.Contains("/home/privacy"))
    {
        // rewrite and continue processing
        context.Request.Path = "/home/index";
    }

    await next();
});

This intercepts every incoming request and checks for a URL to rewrite and when it finds one, change the context.Request.Path and continues processing through the rest of the middleware pipeline. All subsequent middleware components now see the updated path.


You can use a similar approach for Redirecting, but the logic is slightly different because a Redirect is a new request and you'll want to terminate the middleware pipeline:

app.Use(async (context,next) =>
{
    var url = context.Request.Path.Value;

    // Redirect to an external URLif (url.Contains("/home/privacy"))
    {
        context.Response.Redirect("https://markdownmonster.west-wind.com")
        return;   // short circuit
    }

    await next();
});

Unless your target URL includes application external URLs I'd argue there's no good reason to use a Redirect in middleware. It only makes sense for external, non-application URLs in that scenario.

However, Redirects are more commonly used when you need to redirect as part of your application/controller logic, where you can't use a rewrite operation because the path has already been routed to your application endpoint/controller method.


Notice also in the code above that it's a good idea to short-circuit the Response when redirecting, rather than continuing through the rest of the middleware pipeline.


Note also that Response.Redirect() in ASP.NET Core doesn't do automatic path fixups as classic ASP.NET did. You can use: Response.Redirect("~/docs/MarkdownDoc.md") but you have to specify the whole path.


The ASP.NET Core Rewrite Middleware Module

For more complex rewrite and redirect scenarios you can also use the full-fledged ASP.NET Core Rewrite Middleware. It's beyond the scope of this article to go into the details of this complex module, but basically it provides the ability to set regEx based rewrites and redirects and a number of different and some common rewrite operations.


URL rewriting middleware

Using the middleware is great if you have complex rules for many URLs or need follow specific patterns to re-route content. There are also helper for doing common things like routing http:// to https:// and routing the www. url to the root domain.


Here's what the middleware looks like (from the docs):

var options = new RewriteOptions()
            .AddRedirectToHttpsPermanent();
            .AddRedirect("redirect-rule/(.*)", "redirected/$1")
            .AddRewrite(@"^rewrite-rule/(\d+)/(\d+)", 
                                          "rewritten?var1 = $1&var2 = $2", 
             skipRemainingRules: true)
            
        app.UseRewriter(options);



Resource: Microsoft


The Tech Platform

0 comments

Comments


bottom of page