I discovered today that a custom IServiceRunner supplies just the right hooks (see https://github.com/ServiceStack/ServiceStack/wiki/Customize-HTTP-Responses).
As the one above it only works, when the page is served by a Service, because the RequestFilters and the ServiceRunner are not even touched when a ContentPage is requested.
It might be of interest, that the RequestFilter is another hook point, that is called before the Execution of the View. But the same seems true for the ResponseFilter. A small test in which I tried to reset the CurrentUICulture in the ResponseFilter rendered my page unlocalized.
In AppHost
public override void Configure(Funq.Container container)
{
//plugins
Plugins.Add(new RazorFormat());
Plugins.Add(new AuthFeature(() =>
new AuthUserSession(),
new IAuthProvider[] {
new BasicAuthProvider()
}));
//request filters
PreRequestFilters.Add((httpReq, httpResp) =>
{
var session = httpReq.GetSession();
if (session is AuthUserSession)
{
var auths = ((AuthUserSession)session);
if (auths.Culture == null)
{
var languages = httpReq.Headers["Accept-Language"];
auths.Culture = Helpers.CultureHelper.GetBestAcceptLanguageMatch(languages);
httpReq.SaveSession(session, new TimeSpan(0, 20, 0));
}
httpReq.SetItem("Culture", auths.Culture);
}
});
//funq
var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRep);
container.Register<ICacheClient>(c => new MemoryCacheClient());
}
//use a custom IServiceRunner
public override ServiceStack.ServiceHost.IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
{
var runner = base.CreateServiceRunner<TRequest>(actionContext);
return new CultureAwareServiceRunner<TRequest>(this, actionContext);
}
CultureAwareServiceRunner.cs
public class CultureAwareServiceRunner<T> : ServiceRunner<T>
{
public CultureAwareServiceRunner(AppHost appHost, ServiceStack.WebHost.Endpoints.ActionContext actionContext) :
base(appHost, actionContext)
{ }
public override void OnBeforeExecute(IRequestContext requestContext, T request)
{
var httpReq = requestContext.Get<IHttpRequest>();
httpReq.SetItem("PreviousCulture", Thread.CurrentThread.CurrentUICulture);
string culture = httpReq.GetItem("Culture") as string;
if (culture != null)
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
base.OnBeforeExecute(requestContext, request);
}
public override object OnAfterExecute(IRequestContext requestContext, object response)
{
var httpReq = requestContext.Get<IHttpRequest>();
var prevCulture = httpReq.GetItem("PreviousCultureCulture") as CultureInfo;
if (prevCulture != null)
Thread.CurrentThread.CurrentUICulture = prevCulture;
return base.OnAfterExecute(requestContext, response);
}
}