Note that there are some explanatory texts on larger screens.

plurals
  1. POAsync WebApi Thread.CurrentCulture
    primarykey
    data
    text
    <p>I have a self-hosted <strong>OWIN</strong> hosted <strong>Web API</strong> project providing some basic REST methods for me.</p> <p>I want to have multilingual error messages, so I use <strong>Resource</strong> files and a <strong>BaseController</strong> that sets the <strong>Thread.CurrentCulture</strong> and <strong>Thread.CurrentUICulture</strong> to the <strong>Accept-Language</strong> header of the request.</p> <pre><code>public override Task&lt;HttpResponseMessage&gt; ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) { if (controllerContext.Request.Headers.AcceptLanguage != null &amp;&amp; controllerContext.Request.Headers.AcceptLanguage.Count &gt; 0) { string language = controllerContext.Request.Headers.AcceptLanguage.First().Value; var culture = CultureInfo.CreateSpecificCulture(language); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; } base.ExecuteAsync(controllerContext, cancellationToken); } </code></pre> <p>That all works nice, but the problem appears if I make my <strong>controller methods async</strong>.</p> <p>When I use <strong>await</strong> in the method, it might continue in another thread, and so my <strong>CurrentCulture</strong> and <strong>CurrentUICulture</strong> are lost. </p> <p>Here's an little example I used to find this issue.</p> <pre><code>public async Task&lt;HttpResponseMessage&gt; PostData(MyData data) { Thread currentThread = Thread.CurrentThread; await SomeThing(); if (Thread.CurrentThread.CurrentCulture != currentThread.CurrentCulture) Debugger.Break(); } </code></pre> <p>I don't always break in the <strong>Debugger.Break</strong> line, but most of the time I do.</p> <p>Here's an example where I actually use my <strong>Resource File</strong>.</p> <pre><code>public async Task&lt;HttpResponseMessage&gt; PostMyData(MyData data) { //Before this if I'm in the correct thread and have the correct cultures if (await this._myDataValidator.Validate(data) == false) //However, I might be in another thread here, so I have the wrong cultures throw new InvalidMyDataException(); } public class InvalidMyDataException : Exception { public InvalidMyDataException() //Here I access my resource file and want to get the error message depending on the current culture, which might be wrong : base(ExceptionMessages.InvalidMyData) { } } </code></pre> <p>Some additional information: I have a whole bunch of exceptions like this, and they all get caught in an custom <em>ExceptionFilterAttribute</em> which then creates the response.</p> <p>So it would be much code to always set the culture right before I use it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload