Here's my default route:
routes.MapRouteLowercase(
"Default",
"{country}/{controller}/{action}/{id}",
new {
country = "uk",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
},
new[] { "Presentation.Controllers" }
);
As we know, when someone visits www.domain.com/ MVC's routing will determine the default controller and action to execute based upon the above route, but the URL will remain the same. Is there a built in or elegant way to perform a 301 redirect from www.domain.com/ to www.domain.com/uk/{controller}/{action}/ for every route that uses defaults?
This blog suggests the way to change the default route in ASP.NET MVC4. As we know that ASP.NET MVC by default takes following setting available in RouteConfig file (under App_Start folder). This means when you run the application, Home controller will be invoked and it's Index method will be executed by taking parameter id (if any).
Routing in MVC If the URL doesn't contain anything after the domain name, then the default controller and action method will handle the request. For example, http://localhost:1234 would be handled by the HomeController and the Index() method as configured in the default parameter.
Mvc Redirects to the specified route using the specified route values. Redirects to the specified route using the route name. Redirects to the specified route using the route dictionary. Redirects to the specified route using the route name and route values. Redirects to the specified route using the route name and route dictionary.
In this tutorial, you are introduced to an important feature of every ASP.NET MVC application called ASP.NET Routing. The ASP.NET Routing module is responsible for mapping incoming browser requests to particular MVC controller actions. By the end of this tutorial, you will understand how the standard route table maps requests to controller actions.
I have created a custom route handler that does the redirect at the route level. Thanks to Phil Haack.
Here is the complete work.
Redirect route handler
public class RedirectRouteHandler : IRouteHandler
{
private string _redirectUrl;
public RedirectRouteHandler(string redirectUrl)
{
_redirectUrl = redirectUrl;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
if (_redirectUrl.StartsWith("~/"))
{
string virtualPath = _redirectUrl.Substring(2);
Route route = new Route(virtualPath, null);
var vpd = route.GetVirtualPath(requestContext,
requestContext.RouteData.Values);
if (vpd != null)
{
_redirectUrl = "~/" + vpd.VirtualPath;
}
}
return new RedirectHandler(_redirectUrl, false);
}
}
Redirect http handler
public class RedirectHandler : IHttpHandler
{
private readonly string _redirectUrl;
public RedirectHandler(string redirectUrl, bool isReusable)
{
_redirectUrl = redirectUrl;
IsReusable = isReusable;
}
public bool IsReusable { get; private set; }
public void ProcessRequest(HttpContext context)
{
context.Response.Status = "301 Moved Permanently";
context.Response.StatusCode = 301;
context.Response.AddHeader("Location", _redirectUrl);
}
}
Route extensions
public static class RouteExtensions
{
public static void Redirect(this RouteCollection routes, string url, string redirectUrl)
{
routes.Add(new Route(url, new RedirectRouteHandler(redirectUrl)));
}
}
Having all these, I can do something like this while mapping routes in Global.asax.cs.
routes.Redirect("", "/uk/Home/Index");
routes.Redirect("uk", "/uk/Home/Index");
routes.Redirect("uk/Home", "/uk/Home/Index");
.. other routes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With