public async override Task Invoke(IOwinContext owinContext) { System.Web.HttpContextBase context = owinContext.Get <System.Web.HttpContextBase>(typeof(System.Web.HttpContextBase).FullName); Debug.WriteLine("UrlLocalizationMiddleware::Invoke -- ContentType: {0},\n\tUrl: {1}\n\tRawUrl:{2}", context.Response.ContentType, context.Request.Url, context.Request.RawUrl); // Establish the language for the request. That is, we need to call // context.SetPrincipalAppLanguageForRequest with a language, got from the URL, // the i18n.langtag cookie, the Accept-Language header, or failing all that the // default application language. // · If early URL localizer configured, allow it to do it. var rootServices = LocalizedApplication.Current.RootServices; if (UrlLocalizer.UrlLocalizationScheme != UrlLocalizationScheme.Void && rootServices.EarlyUrlLocalizerForApp != null) { rootServices.EarlyUrlLocalizerForApp.ProcessIncoming(context); } // · Otherwise skip the URL aspect and detemrine from the other (inferred) attributes. else { context.SetPrincipalAppLanguageForRequest(context.GetInferredLanguage()); } await Next.Invoke(owinContext); }
// Implementation // Events handlers /// <summary> /// Handler for the BeginRequest ASP.NET request pipeline event, where we inject our /// Early URL Localization logic. /// </summary> private void OnBeginRequest(object sender, EventArgs e) { System.Web.HttpContextBase context = System.Web.HttpContext.Current.GetHttpContextBase(); DebugHelpers.WriteLine("LocalizingModule::OnBeginRequest -- sender: {0}, e:{1}, ContentType: {2},\n\tUrl: {3}\n\tRawUrl:{4}", sender, e, context.Response.ContentType, context.Request.Url, context.Request.RawUrl); // Establish the language for the request. That is, we need to call // context.SetPrincipalAppLanguageForRequest with a language, got from the URL, // the i18n.langtag cookie, the Accept-Language header, or failing all that the // default application language. // · If early URL localizer configured, allow it to do it. if (UrlLocalizer.UrlLocalizationScheme != UrlLocalizationScheme.Void && m_rootServices.EarlyUrlLocalizerForApp != null) { m_rootServices.EarlyUrlLocalizerForApp.ProcessIncoming(context); } // · Otherwise skip the URL aspect and detemrine from the other (inferred) attributes. else { context.SetPrincipalAppLanguageForRequest(context.GetInferredLanguage()); } }
/// <summary> /// Implements the Early Url Localization logic. /// <see href="https://docs.google.com/drawings/d/1cH3_PRAFHDz7N41l8Uz7hOIRGpmgaIlJe0fYSIOSZ_Y/edit?usp=sharing"/> /// </summary> public void ProcessIncoming( System.Web.HttpContextBase context) { // Is URL explicitly excluded from localization? if (!m_urlLocalizer.FilterIncoming(context.Request.Url)) { return; } // YES. Continue handling request. bool allowRedirect = context.Request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase) || context.Request.HttpMethod.Equals("HEAD", StringComparison.OrdinalIgnoreCase); // NO. Is request URL localized? string urlNonlocalized; string langtag = m_urlLocalizer.ExtractLangTagFromUrl(context, context.Request.RawUrl, UriKind.Relative, true, out urlNonlocalized); if (langtag == null) { // NO. // langtag = best match between // 1. Inferred user languages (cookie and Accept-Language header) // 2. App Languages. LanguageTag lt = context.GetInferredLanguage(); // If redirection allowed...redirect user agent (browser) to localized URL. // The principle purpose of this redirection is to ensure the browser is showing the correct URL // in its address field. if (allowRedirect) { RedirectWithLanguage(context, context.Request.RawUrl, lt.ToString(), m_urlLocalizer); return; } // Otherwise, handle the request under the language infered above but without doing the redirect. // NB: this will mean that the user agent (browser) won't have the correct URL displayed; // however, this typically won't be an issue because we are talking about POST, PUT and DELETE methods // here which are typically not shown to the user. else { context.SetPrincipalAppLanguageForRequest(lt); return; // Continue handling request. } } // YES. Does langtag EXACTLY match an App Language? LanguageTag appLangTag = LanguageHelpers.GetMatchingAppLanguage(langtag); if (appLangTag.IsValid() && appLangTag.Equals(langtag)) { // YES. Establish langtag as the PAL for the request. context.SetPrincipalAppLanguageForRequest(appLangTag); // Rewrite URL for this request. context.RewritePath(urlNonlocalized); // Continue handling request. return; } // NO. Does langtag LOOSELY match an App Language? else if (appLangTag.IsValid() && !appLangTag.Equals(langtag)) { // YES. Localize URL with matching App Language. // Conditionally redirect user agent to localized URL. if (allowRedirect) { RedirectWithLanguage(context, urlNonlocalized, appLangTag.ToString(), m_urlLocalizer); return; } } // NO. Do nothing to URL; expect a 404 which corresponds to language not supported. // Continue handling request. }