3

Has anyone had any experienced with making language dependent routes with ASP.NET MVC? What I would like to do is have localized url's to improve SEO. So for example http://mysite.com/products/cars would map to the same controller/action as http://mysite.com/produkter/bilar?

I have tried browsing around a bit, but I could not find anything similar to this. I'm not even convinced it is really such a good idea, but I would imagine that it would help SEO when users are doing searches in their own language. I would imagine this would take some customization of the mvc route engine.

Edit: Mato definitely has the best solution so far, I would like to see a Custom RouteHandler solution though for reference.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
Runeborg
  • 965
  • 1
  • 7
  • 17

4 Answers4

3

One thing with SEO is, if a search engine finds two identical documents on two different links, it may reduce page rank for one of the pages. You need then to translate the page content as well.

3

You could implement an own controller factory class which translates the controller name before initializing it. You could for example store the translations in a resource file or in a DB. The easiest way to do this is to inherit from DefaultControllerFactory and to overwrite the CreateController function.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Web.Mvc
{
    class CustomControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            /**
             * here comes your code for translating the controller name 
             **/

            return base.CreateController(requestContext, controllerName);
        }
    }
}

The last step would be to register your controller factory implementation when the application starts (in the Global.asax).

namespace MyApplication
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
        }
    }
}
Mato
  • 830
  • 2
  • 9
  • 21
  • This definately sounds interesting, unfortunately there is also other parts to the url than the controller name, such as area and action. So I think it is probably best solved at a route level. But maybe this can be handled here as well somehow? – Runeborg Sep 09 '09 at 09:24
  • Since you have access to the Request object through RequestContext you can manipulate every parameter you want to. So there is no problem translating the area or the action at this point. – Mato Sep 10 '09 at 17:49
  • Hm, you mean by modifying the the area/controller/action of routedata? Yes this might work actually if this is evaluated after the route. – Runeborg Sep 11 '09 at 11:24
1

You could use regular expression routes (http://iridescence.no/post/Defining-Routes-using-Regular-Expressions-in-ASPNET-MVC.aspx), and then do something like

routes.Add(new RegexRoute(@"^(Products|Produkter)$", new MvcRouteHandler())
{
    Defaults = new RouteValueDictionary(new { controller = "Products"  })
});
Jan Jongboom
  • 26,598
  • 9
  • 83
  • 120
  • 1
    Yes, this is interesting. But I would like to have a more automated way of doing it. I should probably look more into extending the Route class similar to RegexRoute. – Runeborg Sep 08 '09 at 11:04
0

I won't recommend a Regex based approach because it will be error-prone, other than requiring a strong level of manual customization of all the available URL patterns (wich can be a real pain for non-trivial websites).

Just as @Runeborg said, I strongly recommend a more automated way of doing the job. For MVC 5 (and <) web applications I always use the following one, which I found to be the most versatile one among those I've tried in the latest years.

You basically need to implement three things:

  • A multi-language aware route to handle incoming URLs (if you're using MVC5 or above you could also go for Attribute-based routing instead, but I still prefer to use a global rule to handle this).
  • A LocalizationAttribute to handle these kinds of multi-language requests.
  • An helper method to generate these URLs within your application (Html.ActionLink and/or Url.Action extension methods).

See this answer for further details and code samples.

For additional info and further samples on this topic you can also read this blog post that I wrote on this topic.

Darkseal
  • 9,205
  • 8
  • 78
  • 111