Let your WebApi understand the language context of your request

casper.rasmussen/ November 15, 2016/ Uncategorized/ 7 comments

Working with multi lingual formatting is fairly simple in Episerver CMS. It’s simply a matter of relying on a set of key implementations, such as ContentLanguage.PreferredCulture or CultureInfo.CurrentUICulture, when explicitly formatting an object or struct to it’s localized representation.

One detail, which I’ve seen being left out by developers, is the fact that code executed in the context of an WebApi not by default understands the Episerver language context of a request. In reality, ContentLanguage.PreferredCulture and CultureInfo.CurrentUICulture will, when executed within the scope of ApiController, fall back to a different culture. Issue with this detail is obviously that incorrect formatting will be applied to asynchronous loaded content elements – which unenviable will confuse your Danish speaking audience when they are presented with dates formatted like this: ’11/15/2016′.

There is plenty of ways to deal with this. First let me show you an example of how I’ve seen it being done before – by showing this, my intent is to provide a few reasons to why it’s a bad idea.

What’s not to do – and why

Imagine this simple endpoint, which requires consumers to specify the desired locale, as part of the URL.

HTTP GET /api/blogs/load/?culture=da-DK

Actual implementation is on the other hand a bit more complicated. It quickly unveils a few areas of concern: First off, it allows an API consumer to specify any culture regardless of it being enabled in Episerver or not. Second of all, there is a high potential for it to cause errors – imagine if an API implementation forgot to change the language context prior to converting a birth-date, which later is saved to your CRM system. Last, but not least, nothing validates if it’s a valid ISO culture (exception mayhem).

There is plenty of reasons why you shouldn’t rely on that approach. Instead, let me show you an alternative approach that addresses all of these concerns.

Automatically change the language context of your WebApi requests

Instead of explicitly changing the language context, you should rely on Episerver’s own language branch mechanism. Idea is that your WebApi should rely on dedicated language routes – exactly similar to the way you already serve content. Looking back, the URL used above would instead look like this:

HTTP GET /da-dk/api/blogs/load/

It is fairly simple to activate this. All it takes is for you to enforce a {language} segment as part of your WebApi route templates.

Instead of the previous implementation, which explicitly changed the language context, we now have simpler API implementation. Besides simplicity, it also addresses all above concerns – hurray!

Happy coding!

7 Comments

  1. Hi,
    I’ve solved it by passing the language/culture in Accept-Language header, which is a standard header in the spec, in a few project with great success.

    Best

  2. The truly correct way to do this, would be to let the client do proper content negotiation with your service, and send accepted (“wanted”) languages along in an Accept-Language header. The same techinque is used by default in ASP.NET WebAPI to server JSON or XML on the same address.

  3. Nice. What we did – we were relying on cookie for the language and implemented correct thread culture restore as action filter. which means that you don\’t even need to pass in culture anywhere explicitly.however, there is a downside for this approach – you can\’t easily call from \”no-NB\” context \”da-DK\” service.

  4. Nice – we are also just setting the culture in a request-header. But – I tried out your example and am not getting the correct culture. No matter if my url starts with “da-dk” or “de” it gives me english culture (ContentLanguage.PreferredCulture)

    Where is the Episerver mechanism that would set the culture from the {language} part of the URL ??

    (And shouldn’t it be named {culture} by the way ?)

    Best regards
    Carsten

    1. Hi Carsten.

      Thank you for your questions. Segment has to be called ‘language’, as this is the route value Episerver uses to resolve it’s locale. One of the benefits of using their segment is that Episervers native language branch mechanism will apply. Question is therefore if your ‘da-dk’ and ‘de’ culture is enabled in Episerver?

      /Casper

  5. Hi Casper – the language selection works perfect when routing to the normal MVC controllers for the CMS pages, so the language is turned on. I guess ?

    I tried to set logging to DEBUG but nothing helpful is logged around this.

    Anything else I can check ?

    Best regards
    Carsten

    P.S. Er du dansker ? 😉

    1. Hi Carsten.

      Yes, that indicates the language has been turned on.
      It’s a prerequisite that your route values, resolved through your route template, contains the value “da-dk” for an item identified as “language”. That’s be where my diagnosis would start.

      To your question; Yes, I am danish – though living in the US.

      Hope you are able to make it work as expected.

      /Casper

Leave a Comment

Your email address will not be published. Required fields are marked *

Please type the characters of this captcha image in the input box

Please type the characters of this captcha image in the input box
You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
*
*