Sorry to hijack my own thread again, but I still cannot create any new thread in the forum
I've been struggling with accessing the proper current locale from a HttpModule handling the PostRequestHandlerExecute event.
Here is what I'm stuck with:
- As a reminder, the Dnn Locale is set during the DotNetNuke.Framework.PageBase.OnInit method call
- the PageCulture Property getter figures out the proper culture to apply according to the various fallback strategies (query/cookie, profile, browser…)
- Along the way, a cookie is set with the corresponding locale through Localization.SetLanguage(strValue)
- The culture is then applied to the Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture
- New Localization().CurrentCulture is really a shortcut to Thread.CurrentThread.CurrentCulture, which returns the expected value anywhere during the Handler execution
- There are two layers of .Net code that prevent accessing such a value after the handler execution (i.e in a HttpModule or a ResponseFilter for instance):
- The System.Web.UI.Page.ProcessRequest() method retrieves the current thread culture before processing and calls RestoreCultures(ByVal currentThread As Thread, ByVal prevCulture As CultureInfo, ByVal prevUICulture As CultureInfo) after processing, thus undoing any change made during the page life cycle
- Both ApplicationStepManager and PipelineStateManager from System.Web.HttpApplication do wrap any async call to ResumeSteps with calls to HttpApplication.ThreadContext.Enter and HttpApplication.ThreadContext.Leave which involve calls to ThreadContext.SetRequestLevelCulture and ThreadContext.RestoreRequestLevelCulture.
Similarly to the Page.ProcessRequest method, those calls result in the current thread culture being saved and restored on each asynchronous step call
- I hoped I could get some help from the following:
- The System.Web.Page class offers an Overridable Sub InitializeCulture() as an alternative to deal with the current culture, a call to that method is dynamically inserted by the System.Web.Compilation.BaseTemplateCodeDomTreeGenerator.BuildBuildMethodInternal when the IHttpHandler for the aspx is built.
- The ThreadContext.SetRequestLevelCulture method alternatively relies on the Page.DynamicCulture and DynamicUICulture properties if available, which in turns are affected by the System.Web.Page.Culture and System.Web.Page.UICulture properties
- Accordingly, I thought I could get away with updating the DotNetNuke.Framework.PageBase class such that:
- The locale init logic is place in the InitializeCulture rather than OnInit
- The Page.Culture and Page.UICulture are both set, rather than simply the Thread.CurrentThread.CurrentCulture and UI counter part
Unfortunately, that did not solve my issue. Immediately after Handler completion, the thread culture still resets to en-Us (as defined in my web.config file, probably because in classic mode as well as in integrated mode, the steps are executed synchronously).
I guess I will have to rely on the response cookie for now (defined during PageBase Init by Localization.SetLocale), which should be ok although I don’t like that idea so much.
Does anyone have a better idea?
In the mean time, I reckon that what I’m experiencing was not the expected behavior when relying on the thread culture in the first place, and it should not be difficult to provide a reliable location for the culture, for instance in the PortalSettings.
One might argue that since there is a fallback based on the User Profile, its value must be defined after authentication, rather than on the BeginRequest event as the PortalSettings. However I think that can be mitigated:
- Since the cookie value has priority over the profile value, I guess there are only very rare cases when the profile value is actually taken into account (AD authentication is one I can think of)
- I don’t see any problem redefining the value on PostAuthenticate or PageInit event if needed, since for now we don’t have access to the proper culture beforehand anyway.
Thanks for reading so far, and for any further advices.