Search code examples
asp.netasp.net-mvcasp.net-mvc-5routesasp.net-mvc-5.2

Routing code working in ASP.NET MVC 5.0 no longer works in 5.2


I have code that runs on application start that prefixes all of my routes with a {lang} parameter.

The intent is to transform any URL like /page to {lang}/page, with {lang} being a language code ("en", "fr"...).

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapMvcAttributeRoutes();

    foreach (var r in routes.OfType<Route>())
        r.Url = "{lang}/" + r.Url;
}

This works fine on ASP.NET MVC 5.0. For example this action shows the About page on both /en/about-us and /fr/about-us:

[Route("about-us", Name = "About")]
public ActionResult About()
{
    return View();
}

(the {lang} parameter is read in OnActionExecuting and sets the UI culture accordingly.)

However, it no longer works on ASP.NET MVC 5.2.3.

On this version, the page remains accessible on /abous-us, and /en/about-us and /fr/about-us return a 404. It is like the modified routes are not taken into account.

I tried to dig into MapMvcAttributeRoutes to troubleshoot but it looks like the code, and in particular the AttributeRoutingMapper class, was completely rewritten between the 2 versions.

Is there anything I can do to have my modified routes taken into account?


Solution

  • Without modifying already registered routes, preferred approach would be to use RoutePrefix attribute on controller:

    [RoutePrefix("{lang}")]
    public class HomeController : Controller
    {
        [Route("~/", Name = "Index")] // Use ~ to skip prefix or use optional {lang?} as prefix
        public ActionResult Index()
        {
            return View();
        }
    
        [Route("about-us", Name = "About")]
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
    
            return View();
        }
    
        [Route("contact", Name = "Contact")]
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
    
            return View();
        }
        ...
    }
    

    as to why it is not working, unfortunately without looking at the code or comparing routes in both versions you will not have any logical answer.