Reputation: 16322
In asp.net 4.0 we can use work with the http module to rewrite module like so:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string CountryCodeInUrl = "", redirectUrl="";
var countryCode = CookieSettings.ReadCookie();
if (countryCode=="")
{
countryCode = "gb";
}
if (HttpContext.Current.Request.RawUrl.Length >= 2)
{
CountryCodeInUrl = HttpContext.Current.Request.RawUrl.Substring(1, 2);
}
if (countryCode != CountryCodeInUrl)
{
if (HttpContext.Current.Request.RawUrl.Length >= 2)
{
if (HttpContext.Current.Request.RawUrl.Substring(1, 2) != "")
{
countryCode = HttpContext.Current.Request.RawUrl.Substring(1, 2);
}
}
if(!System.Web.HttpContext.Current.Request.RawUrl.Contains(countryCode))
{
redirectUrl = string.Format("/{0}{1}", countryCode, System.Web.HttpContext.Current.Request.RawUrl);
}
else
{
redirectUrl = System.Web.HttpContext.Current.Request.RawUrl;
}
CookieSettings.SaveCookie(countryCode);
System.Web.HttpContext.Current.Response.RedirectPermanent(redirectUrl);
}
}
How could I rewrite the code above using middleware in ASP.NET Core?
I have just partially read this article: https://learn.microsoft.com/en-us/aspnet/core/migration/http-modules
Upvotes: 10
Views: 11835
Reputation: 17681
As long as you insert the rewrite middleware before other middleware that fires you can re-write the Context.Request.Path
in the middleware code.
The Path is writable and any subsequent code/middleware will use the new path to process the request.
Using self-contained (app.Use()) middleware you can do:
app.Use(async (context,next) =>
{
var url = context.Request.Path.Value;
// Rewrite privacy URL to index
if (url.Contains("/home/privacy"))
{
// rewrite to index
context.Request.Path = "/home/index";
}
await next();
});
Unlike the Repsonse.Redirect()
(which fires a new server request) the URL of the original request is not changed by this operation.
More info in this blog post:
Back to Basics: URL Rewriting in ASP.NET Core
Upvotes: 8
Reputation: 2840
You pretty much just need to move the code to a middleware class, and use the Core HttpContext instead of the System.Web one.
A class like that would look like this:
//RedirectMiddleware.cs
public class RedirectMiddleware
{
private readonly RequestDelegate _next;
public RedirectMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
string CountryCodeInUrl = "", redirectUrl = "";
var countryCode = CookieSettings.ReadCookie();
if (countryCode == "")
{
countryCode = "gb";
}
if (context.Request.Path.Value.Length >= 2)
{
CountryCodeInUrl = context.Request.Path.Value.Substring(1, 2);
}
if (countryCode != CountryCodeInUrl)
{
if (context.Request.Path.Value.Length >= 2)
{
if (context.Request.Path.Value.Substring(1, 2) != "")
{
countryCode = context.Request.Path.Value.Substring(1, 2);
}
}
if (!context.Request.Path.Value.Contains(countryCode))
{
redirectUrl = string.Format("/{0}{1}", countryCode, context.Request.Path.Value);
}
else
{
redirectUrl = context.Request.Path.Value;
}
CookieSettings.SaveCookie(countryCode);
context.Response.Redirect(redirectUrl, true);
}
await _next.Invoke(context);
}
}
To use it you then register it in you Startup.cs file, before you register the MVC middleware, like this:
app.UseMiddleware<RedirectMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
I hope this'll get you started, you can see this blog post for more information on middleware.
Upvotes: 9