0

Background

I've inherited an e-commerce website using the usual aspnet's MVC5 / razor / jQuery. The goal is globalizing the website and add a language selector, to support the two main country/language targeting strategies. I've just accomplished the first step, which is routing the website so it handles domain.com/en/, domain.com/es/, domain.com/es-mx/... Using http://jittuu.com/2014/3/17/AspNet-localization-routing After this, entering the domain with a non-existent locale redirects to the default one. There's a custom IRouteHandler that get's the httprequest, checks the locale and puts it if it needs to:

Public Class LocalizationRedirectRouteHandler
    Implements IRouteHandler

    Public Function GetHttpHandler(requestContext As RequestContext) As IHttpHandler Implements IRouteHandler.GetHttpHandler

        Dim routeValues = requestContext.RouteData.Values
        Dim cookieLocale = requestContext.HttpContext.Request.Cookies("locale")
        If cookieLocale IsNot Nothing Then
            routeValues("culture") = cookieLocale.Value
            Return New RedirectHandler(New UrlHelper(requestContext).RouteUrl(routeValues))
        End If

        Dim uiCulture = CultureInfo.CurrentUICulture
        routeValues("culture") = uiCulture.Name
        Return New RedirectHandler(New UrlHelper(requestContext).RouteUrl(routeValues))

    End Function
End Class

There are thousands of "inline" AJAX calls to routes across the website written without an @Html helper because the project has separate, bundled js files, failing. There are hundreds of routes failing because the project controllers are using attribute routing and it's not specifying locale. For example, a simple link to a product features is failing because the controller has a route specifying

/product/{id}

but the URL looks like

/es-MX/product/{id}

Question:

What's the right way to proceed here?

I was expecting those AJAX and links without locale to be redirected, but they are not.

Should I rewrite all those files so they specify current locale? Is there any other "healthy" way to do this, like extending BaseController and add culture as a route prefix?

Thank you in advance for your time, I'm terribly lost here.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
MWS
  • 3
  • 6
  • See [ASP.NET MVC 5 culture in route and url](https://stackoverflow.com/q/32764989/181087). That describes how you can fix `AttributeRouting` to handle this. However, the approach in the article you linked has issues 1) It uses redirects, rather than routing to move around the site (very bad for SEO) 2) It uses an HTTP Handler rather than just extending routing 3) It extends `MvcRouteHandler` rather than `RouteBase`. `RouteBase` handles routing 2-ways (including URL generation) and `MvcRouteHandler` only handles matching incoming requests. – NightOwl888 Jan 23 '18 at 12:19
  • I've been toying with your suggestion and I could make it work, @NightOwl888. Turns out, first time I tried it, I failed to see the attribute part. I'm going to set this as the correct answer, so thank you a lot. From what I've understood this second time, the constraint's default culture works in the website's no-lang-directory-URL. **Is this the desired effect or it's a bad behaviour of my project?** Also, do you have any insight on how to approach URL/route localization? Should the locale on the URL be en or en-UK, en-US...? – MWS Jan 24 '18 at 08:46
  • Yes, the idea is to set the default culture to use the "standard" URL, and then any additional locales will explicitly have a culture in them. If you want to also localize your URLs, there is an open source project that may help [RouteLocalization](https://github.com/Dresel/RouteLocalization). And yes, you can use either the `en` or the `en-GB` format with this approach, the latter you will need to adjust the regex, prefix, etc to work with that format. – NightOwl888 Jan 24 '18 at 09:34
  • @NightOwl888 Thank you very much!! – MWS Jan 24 '18 at 10:06

1 Answers1

0

Turns out, this answer by @NightOwl888 is the closest I've found to a solution to the problem I was facing. After including this changes to my project, I have almost everything working out and sporting a wonderful culture prefix on the URL. There's still a few things to work out though:

  1. My default route sports no culture in the URL, wich may be against one of our goals. I can work on that toying (or removing) the defaultCulture constraint.
  2. There are hundreds of windows.location on js files targeting routes without culture. I may be able to work on that via JS global variable storing the culture.
  3. I still need to find a nice way to handle URL localization. Hopefully this project will help me through (also directed there by @NightOwl888).
MWS
  • 3
  • 6