ASP.NET Core – Return a redirect response

A redirect response contains a redirect status code (3xx) and a redirect URL in the Location header. The redirect URL can be an absolute or relative path. It’s up to the client to follow the redirect properly.

Here’s an example of returning a redirect response using the Redirect() helper method:

[ApiController] [Route("[controller]")] public class ContentController : ControllerBase { [HttpGet("getallmovies")] public IActionResult GetAllMovies() { return Redirect("/movies/"); } }
Code language: C# (cs)

Note: The redirect helper methods are defined in the ControllerBase abstract base class.

When a request comes in, this returns the following redirect response:

Status Code: 302 (Found) Location: /movies/
Code language: plaintext (plaintext)

To follow the redirect, the client has to issue a new request (i.e. GET https://localhost:12345/movies/).

There are many redirect helper methods available. Some help you build the redirect URL, while others (with very long names) simply help you return a specific redirect status code. Alternatively, you can return a RedirectResult:

//these are equivalent return new RedirectResult("/movies/", permanent: true, preserveMethod: true); return RedirectPermanentPreserveMethod("/movies/");
Code language: C# (cs)

Four main types of redirects

There are two properties that define a redirect. These indicate to the client how the redirect should be handled:

  • Permanent: Is the redirect permanent or temporary? If it’s permanent, it’d be best to send future requests to the new URL.
  • Preserve Method: Should the original HTTP method (GET/POST/DELETE/PUT) be used when following the request?

The four main types of redirects are combinations of these two properties. The following table shows these four types:

Status CodePermanent?Preserve Method?Helper method

More about Preserve Method redirects

301 and 302 are not Preserve Method redirects. The standard convention* is for clients to do a Forced GET when following a 301/302 redirect. This means they will issue the request to the redirect URL using a GET instead of the original HTTP method.

In general, if you’re returning a redirect response for a non-GET request, you should consider using one of the Preserve Method redirects (307/308).

* Postman and HttpClient follow this standard convention by default. Of course, the dev can always customize this behavior. Be sure to explicitly state in your API docs what redirect status codes you’re returning and how the client-side should handle them (if non-standard).

Redirect from middleware

You can add your own middleware for handling redirects in a centralized, and more efficient, manner. This is good if you need to handle many redirect scenarios. It’s more efficient than redirecting from individual controller methods because you can short-circuit the request (because the middleware is executed much earlier in the request pipeline), therefore preventing unnecessary work.

Here’s an example of adding a middleware class that handles redirects:

public class RedirectMiddleware { private readonly RequestDelegate NextMiddleware; public RedirectMiddleware(RequestDelegate nextMiddleware) { NextMiddleware = nextMiddleware; } public async Task InvokeAsync(HttpContext context) { //1 - Check the request path for redirect conditions if (context.Request.Path == "/content/getallmovies/") { //2 - Redirect context.Response.Redirect("/movies/", permanent: true, preserveMethod: true); return; } //3 - Otherwise call the next middleware await NextMiddleware(context); } }
Code language: C# (cs)

You can check the request path for any redirect conditions you want – exact matches, partial matches, starts or ends with a certain value.

To actually use the middleware, add it in Startup.Configure():

public class Startup { //rest of class public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseMiddleware<RedirectMiddleware>(); //rest of method } }
Code language: C# (cs)

The order that you add middleware (call UseMiddleware()) determines their position in the request pipeline. So add the redirect middleware near the top, but below UseHttpsRedirection() (because HTTP to HTTPS redirects should take priority).

HTTP to HTTPS redirects

You can use the built-in HttpsRedirectionMiddleware for handling HTTP to HTTPS redirects. When the client makes a request using HTTP, it returns a redirect response with the HTTPS equivalent of the URL and status code 307.

To use this, add app.UseHttpRedirection() in Startup.Configure():

public class Startup { //rest of class public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); //rest of method } }
Code language: C# (cs)

Note: Add app.UseHsts() if this is for a website running in a browser.

Change redirect status code

You can configure HTTPS redirection by calling services.AddHttpsRedirections(…) in Startup.ConfigureServices() and setting the options. For example, this is making it use the 308 redirect response code instead of the default value of 307:

using Microsoft.AspNetCore.Http; public class Startup { //rest of class public void ConfigureServices(IServiceCollection services) { services.AddHttpsRedirection(options => { options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect; }); //rest of method } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); //rest of method } }
Code language: C# (cs)

Leave a Comment