public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext) { string cultureCode = null; if (httpContext.Request.Path.HasValue && httpContext.Request.Path.Value.Length >= 4 && httpContext.Request.Path.Value[0] == '/' && httpContext.Request.Path.Value[3] == '/') cultureCode = httpContext.Request.Path.Value.Substring(1, 2); else cultureCode = "en"; CultureInfo culture = CultureInfoCache.GetCultureInfo(cultureCode); CultureInfo uiCulture = CultureInfoCache.GetCultureInfo(cultureCode); RequestCulture requestCulture = new RequestCulture(culture, uiCulture); requestCulture = this.ValidateRequestCulture(requestCulture); return Task.FromResult(requestCulture); }
/// <summary> /// Adds the <see cref="RequestLocalizationMiddleware"/> to automatically set culture information for /// requests based on information provided by the client using the default options. /// </summary> /// <param name="app">The <see cref="IApplicationBuilder"/>.</param> /// <param name="defaultRequestCulture">The default <see cref="RequestCulture"/> to use if none of the /// requested cultures match supported cultures.</param> /// <returns>The <see cref="IApplicationBuilder"/>.</returns> public static IApplicationBuilder UseRequestLocalization( this IApplicationBuilder app, RequestCulture defaultRequestCulture) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (defaultRequestCulture == null) { throw new ArgumentNullException(nameof(defaultRequestCulture)); } var options = new RequestLocalizationOptions(); return UseRequestLocalization(app, options, defaultRequestCulture); }
public async void CustomRequestCultureProviderThatGetsCultureInfoFromUrl() { using (var server = TestServer.Create(app => { var options = new RequestLocalizationOptions(); options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context => { var culture = GetCultureInfoFromUrl(context); var requestCulture = new RequestCulture(culture); return Task.FromResult(requestCulture); })); app.UseRequestLocalization(options); app.Run(context => { var requestCultureFeature = context.Features.Get<IRequestCultureFeature>(); var requestCulture = requestCultureFeature.RequestCulture; Assert.Equal("ar", requestCulture.Culture.Name); return Task.FromResult(0); }); })) { var client = server.CreateClient(); var response = await client.GetAsync("/ar/page"); } }
public async void GetCultureInfoFromPersistentCookie() { using (var server = TestServer.Create(app => { var options = new RequestLocalizationOptions(); var provider = new CookieRequestCultureProvider(); provider.CookieName = "Preferences"; options.RequestCultureProviders.Insert(0, provider); app.UseRequestLocalization(options); app.Run(context => { var requestCultureFeature = context.Features.Get<IRequestCultureFeature>(); var requestCulture = requestCultureFeature.RequestCulture; Assert.Equal("ar-SA", requestCulture.Culture.Name); return Task.FromResult(0); }); })) { var client = server.CreateClient(); var culture = new CultureInfo("ar-SA"); var requestCulture = new RequestCulture(culture); var value = CookieRequestCultureProvider.MakeCookieValue(requestCulture); client.DefaultRequestHeaders.Add("Cookie", new CookieHeaderValue("Preferences", value).ToString()); var response = await client.GetAsync(string.Empty); Assert.Equal("c=ar-SA|uic=ar-SA", value); } }
/// <summary> /// Creates a new <see cref="RequestCultureFeature"/> with the specified <see cref="Localization.RequestCulture"/>. /// </summary> /// <param name="requestCulture">The <see cref="Localization.RequestCulture"/>.</param> /// <param name="provider">The <see cref="IRequestCultureProvider"/>.</param> public RequestCultureFeature(RequestCulture requestCulture, IRequestCultureProvider provider) { if (requestCulture == null) { throw new ArgumentNullException(nameof(requestCulture)); } RequestCulture = requestCulture; Provider = provider; }
private static void SetCurrentThreadCulture(RequestCulture requestCulture) { #if DNX451 Thread.CurrentThread.CurrentCulture = requestCulture.Culture; Thread.CurrentThread.CurrentUICulture = requestCulture.UICulture; #else CultureInfo.CurrentCulture = requestCulture.Culture; CultureInfo.CurrentUICulture = requestCulture.UICulture; #endif }
/// <inheritdoc /> public override Task <RequestCulture> DetermineRequestCulture([NotNull] HttpContext httpContext) { var request = httpContext.Request; if (!request.QueryString.HasValue) { return(Task.FromResult((RequestCulture)null)); } string queryCulture = null; string queryUICulture = null; if (!string.IsNullOrWhiteSpace(QueryStringKey)) { queryCulture = request.Query[QueryStringKey]; } if (!string.IsNullOrWhiteSpace(UIQueryStringKey)) { queryUICulture = request.Query[UIQueryStringKey]; } if (queryCulture == null && queryUICulture == null) { // No values specified for either so no match return(Task.FromResult((RequestCulture)null)); } if (queryCulture != null && queryUICulture == null) { // Value for culture but not for UI culture so default to culture value for both queryUICulture = queryCulture; } if (queryCulture == null && queryUICulture != null) { // Value for UI culture but not for culture so default to UI culture value for both queryCulture = queryUICulture; } var culture = CultureInfoCache.GetCultureInfo(queryCulture); var uiCulture = CultureInfoCache.GetCultureInfo(queryUICulture); if (culture == null || uiCulture == null) { return(Task.FromResult((RequestCulture)null)); } var requestCulture = new RequestCulture(culture, uiCulture); requestCulture = ValidateRequestCulture(requestCulture); return(Task.FromResult(requestCulture)); }
/// <summary> /// Creates a new <see cref="RequestLocalizationOptions"/> with default values. /// </summary> public RequestLocalizationOptions() { DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); RequestCultureProviders = new List<IRequestCultureProvider> { new QueryStringRequestCultureProvider { Options = this }, new CookieRequestCultureProvider { Options = this }, new AcceptLanguageHeaderRequestCultureProvider { Options = this } }; }
/// <summary> /// Creates a string representation of a <see cref="RequestCulture"/> for placement in a cookie. /// </summary> /// <param name="requestCulture">The <see cref="RequestCulture"/>.</param> /// <returns>The cookie value.</returns> public static string MakeCookieValue(RequestCulture requestCulture) { if (requestCulture == null) { throw new ArgumentNullException(nameof(requestCulture)); } var seperator = _cookieSeparator[0].ToString(); return(string.Join(seperator, $"{_culturePrefix}{requestCulture.Culture.Name}", $"{_uiCulturePrefix}{requestCulture.UICulture.Name}")); }
/// <summary> /// Creates a string representation of a <see cref="RequestCulture"/> for placement in a cookie. /// </summary> /// <param name="requestCulture">The <see cref="RequestCulture"/>.</param> /// <returns>The cookie value.</returns> public static string MakeCookieValue(RequestCulture requestCulture) { if (requestCulture == null) { throw new ArgumentNullException(nameof(requestCulture)); } var seperator = _cookieSeparator[0].ToString(); return string.Join(seperator, $"{_culturePrefix}{requestCulture.Culture.Name}", $"{_uiCulturePrefix}{requestCulture.UICulture.Name}"); }
/// <summary> /// Creates a new <see cref="RequestLocalizationOptions"/> with default values. /// </summary> public RequestLocalizationOptions() { DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture); RequestCultureProviders = new List <IRequestCultureProvider> { new QueryStringRequestCultureProvider { Options = this }, new CookieRequestCultureProvider { Options = this }, new AcceptLanguageHeaderRequestCultureProvider { Options = this } }; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); // Configure the Localization middleware var culture = new RequestCulture(new CultureInfo("en-US"), new CultureInfo("en-US")); app.UseRequestLocalization(culture); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Home/Error"); // For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859 try { using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>() .CreateScope()) { serviceScope.ServiceProvider.GetService<ApplicationDbContext>() .Database.Migrate(); } } catch { } } app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear()); app.UseStaticFiles(); app.UseIdentity(); // To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
/// <inheritdoc /> public override Task <RequestCulture> DetermineRequestCulture([NotNull] HttpContext httpContext) { var acceptLanguageHeader = httpContext.Request.GetTypedHeaders().AcceptLanguage; if (acceptLanguageHeader == null || acceptLanguageHeader.Count == 0) { return(Task.FromResult((RequestCulture)null)); } var languages = acceptLanguageHeader.AsEnumerable(); if (MaximumAcceptLanguageHeaderValuesToTry > 0) { // We take only the first configured number of languages from the header and then order those that we // attempt to parse as a CultureInfo to mitigate potentially spinning CPU on lots of parse attempts. languages = languages.Take(MaximumAcceptLanguageHeaderValuesToTry); } var orderedLanguages = languages.OrderByDescending(h => h, StringWithQualityHeaderValueComparer.QualityComparer) .ToList(); foreach (var language in orderedLanguages) { // Allow empty string values as they map to InvariantCulture, whereas null culture values will throw in // the CultureInfo ctor if (language.Value != null) { var culture = CultureInfoCache.GetCultureInfo(language.Value); if (culture != null) { var requestCulture = new RequestCulture(culture); requestCulture = ValidateRequestCulture(requestCulture); if (requestCulture != null) { return(Task.FromResult(requestCulture)); } } } } return(Task.FromResult((RequestCulture)null)); }
/// <summary> /// Adds the <see cref="RequestLocalizationMiddleware"/> to automatically set culture information for /// requests based on information provided by the client. /// </summary> /// <param name="app">The <see cref="IApplicationBuilder"/>.</param> /// <param name="options">The options to configure the middleware with.</param> /// <param name="defaultRequestCulture">The default <see cref="RequestCulture"/> to use if none of the /// requested cultures match supported cultures.</param> /// <returns>The <see cref="IApplicationBuilder"/>.</returns> public static IApplicationBuilder UseRequestLocalization( this IApplicationBuilder app, RequestLocalizationOptions options, RequestCulture defaultRequestCulture) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (defaultRequestCulture == null) { throw new ArgumentNullException(nameof(defaultRequestCulture)); } return app.UseMiddleware<RequestLocalizationMiddleware>(options, defaultRequestCulture); }
/// <summary> /// Creates a new <see cref="RequestLocalizationMiddleware"/>. /// </summary> /// <param name="next">The <see cref="RequestDelegate"/> representing the next middleware in the pipeline.</param> /// <param name="options">The <see cref="RequestLocalizationOptions"/> representing the options for the /// <see cref="RequestLocalizationMiddleware"/>.</param> /// <param name="defaultRequestCulture">The default <see cref="RequestCulture"/> to use if none of the /// requested cultures match supported cultures.</param> public RequestLocalizationMiddleware( RequestDelegate next, RequestLocalizationOptions options, RequestCulture defaultRequestCulture) { if (next == null) { throw new ArgumentNullException(nameof(next)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (defaultRequestCulture == null) { throw new ArgumentNullException(nameof(defaultRequestCulture)); } _next = next; _options = options; _defaultRequestCulture = defaultRequestCulture; }
/// <summary> /// Creates a new <see cref="RequestLocalizationMiddleware"/>. /// </summary> /// <param name="next">The <see cref="RequestDelegate"/> representing the next middleware in the pipeline.</param> /// <param name="options">The <see cref="RequestLocalizationOptions"/> representing the options for the /// <see cref="RequestLocalizationMiddleware"/>.</param> /// <param name="defaultRequestCulture">The default <see cref="RequestCulture"/> to use if none of the /// requested cultures match supported cultures.</param> public RequestLocalizationMiddleware( RequestDelegate next, RequestLocalizationOptions options, RequestCulture defaultRequestCulture) { if (next == null) { throw new ArgumentNullException(nameof(next)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } if (defaultRequestCulture == null) { throw new ArgumentNullException(nameof(defaultRequestCulture)); } _next = next; _options = options; _defaultRequestCulture = defaultRequestCulture; }
/// <summary> /// Invokes the logic of the middleware. /// </summary> /// <param name="context">The <see cref="HttpContext"/>.</param> /// <returns>A <see cref="Task"/> that completes when the middleware has completed processing.</returns> public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var requestCulture = _defaultRequestCulture; IRequestCultureProvider winningProvider = null; if (_options.RequestCultureProviders != null) { foreach (var provider in _options.RequestCultureProviders) { var providerResultCulture = await provider.DetermineProviderCultureResult(context); if (providerResultCulture != null) { var cultures = providerResultCulture.Cultures; var uiCultures = providerResultCulture.UICultures; CultureInfo cultureInfo = null; CultureInfo uiCultureInfo = null; if (_options.SupportedCultures != null) { cultureInfo = GetCultureInfo(cultures, _options.SupportedCultures); } if (_options.SupportedUICultures != null) { uiCultureInfo = GetCultureInfo(uiCultures, _options.SupportedUICultures); } if (cultureInfo == null && uiCultureInfo == null) { continue; } if (cultureInfo == null && uiCultureInfo != null) { cultureInfo = _defaultRequestCulture.Culture; } if (cultureInfo != null && uiCultureInfo == null) { uiCultureInfo = _defaultRequestCulture.UICulture; } var result = new RequestCulture(cultureInfo, uiCultureInfo); if (result != null) { requestCulture = result; winningProvider = provider; break; } } } } context.Features.Set <IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider)); SetCurrentThreadCulture(requestCulture); await _next(context); }
// Configure is called after ConfigureServices is called. // you can change this method signature to include any dependencies that need to be injected into this method // you can see we added the dependency for IOptions<MultiTenantOptions> // so basically if you need any service in this method that was previously setup in ConfigureServices // you can just add it to the method signature and it will be provided by dependency injection public void Configure( IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<MultiTenantOptions> multiTenantOptions, IServiceProvider serviceProvider, ILogRepository logRepository) { // Configure the HTTP request pipeline. // LogLevels //Debug = 1, //Verbose = 2, //Information = 3, //Warning = 4, //Error = 5, //Critical = 6, loggerFactory.MinimumLevel = LogLevel.Information; // Add the console logger. loggerFactory.AddConsole(); // Add cloudscribe db logging loggerFactory.AddDbLogger(serviceProvider, logRepository); //app.UseCultureReplacer(); // localization from .resx files is not really working in beta8 // will have to wait till next release var localizationOptions = new RequestLocalizationOptions { // Set options here to change middleware behavior //DefaultRequestCulture = new RequestCulture(new CultureInfo("en-US")), SupportedCultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("it"), new CultureInfo("fr") }, SupportedUICultures = new List<CultureInfo> { new CultureInfo("en-US"), new CultureInfo("it"), new CultureInfo("fr") } }; // Optionally create an app-specific provider with just a delegate, e.g. look up user preference from DB. // Inserting it as position 0 ensures it has priority over any of the default providers. //options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context => //{ //})); //app.UseRequestLocalization(localizationOptions); var defaultCulture = new RequestCulture(new CultureInfo("en-US")); //app.UseRequestLocalization(localizationOptions, defaultCulture); // Add the following to the request pipeline only in development environment. if (env.IsEnvironment("Development")) { //app.UseBrowserLink(); app.UseDeveloperExceptionPage(); //app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll); //app.UseStatusCodePagesWithReExecute("/error/{0}"); //app.UseStatusCodePagesWithReExecute("/error/{0}"); } else { // Add Error handling middleware which catches all application specific errors and // sends the request to the following path or controller action. //app.UseErrorHandler("/Home/Error"); //app.UseErrorPage(ErrorPageOptions.ShowAll); // handle 404 and other non success //app.UseStatusCodePages(); // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain")); // app.UseStatusCodePages("text/plain", "Response, status code: {0}"); // app.UseStatusCodePagesWithRedirects("~/errors/{0}"); // PathBase relative // app.UseStatusCodePagesWithRedirects("/base/errors/{0}"); // Absolute // app.UseStatusCodePages(builder => builder.UseWelcomePage()); //app.UseStatusCodePagesWithReExecute("/errors/{0}"); //app.UseStatusCodePagesWithReExecute("/error/{0}"); } // Add the platform handler to the request pipeline. //app.UseIISPlatformHandler(); app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear()); //app.UseRuntimeInfoPage("/info"); // Add static files to the request pipeline. app.UseStaticFiles(); // the only thing we are using session for is Alerts app.UseSession(); //app.UseInMemorySession(configure: s => s.IdleTimeout = TimeSpan.FromMinutes(20)); // this is in Startup.CloudscribeCore.cs app.UseCloudscribeCore(multiTenantOptions,Configuration); // it is very important that all authentication configuration be set before configuring mvc // ie if app.UseFacebookAuthentication(); was below app.UseMvc the facebook login button will not be shown // Add MVC to the request pipeline. app.UseMvc(routes => { // Understanding ASP.NET Routing: // it is very important that routes are registered in the correct order. more specific routes must be registered first and // less specific routes must be registered later. a request may match more than one route. // When a request comes in it is compared to routes in the route table and the first route it matches is used no matter if a // better match exists. therefore if a less specific route is registered first it will catch requests that would have a better // match with a more specific route that was registered later. // ie the default route is usually the least specific route and must be registered last // something like a route for a cms would likely need to be the default route added last especially if you are not going to use // a controller segment in the route because without a controller segment the route is less specific // default route for folder sites must be second to last if (multiTenantOptions.Value.Mode == MultiTenantMode.FolderName) { routes.MapRoute( name: "folderdefault", template: "{sitefolder}/{controller}/{action}/{id?}", defaults: new { controller = "Home", action = "Index" }, constraints: new { name = new SiteFolderRouteConstraint() } ); } // the default route has to be added last routes.MapRoute( name: "default", template: "{controller}/{action}/{id?}", defaults: new { controller = "Home", action = "Index" } ); // Uncomment the following line to add a route for porting Web API 2 controllers. // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); }) ; // https://github.com/aspnet/Announcements/issues/54 // if you want to run the IIS pipeline for requests not handled // ie you won't see the IIS 404 page without this. // if nothing else handles the 404 then you get a blank white page in the browser //app.RunIISPipeline(); //app.Run(context => //{ // context.Response.StatusCode = 404; // return Task.FromResult(0); //}); }
/// <summary> /// Invokes the logic of the middleware. /// </summary> /// <param name="context">The <see cref="HttpContext"/>.</param> /// <returns>A <see cref="Task"/> that completes when the middleware has completed processing.</returns> public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var requestCulture = _options.DefaultRequestCulture; IRequestCultureProvider winningProvider = null; if (_options.RequestCultureProviders != null) { foreach (var provider in _options.RequestCultureProviders) { var providerResultCulture = await provider.DetermineProviderCultureResult(context); if (providerResultCulture != null) { var cultures = providerResultCulture.Cultures; var uiCultures = providerResultCulture.UICultures; CultureInfo cultureInfo = null; CultureInfo uiCultureInfo = null; if (_options.SupportedCultures != null) { cultureInfo = GetCultureInfo( cultures, _options.SupportedCultures, _options.FallBackToParentCultures); } if (_options.SupportedUICultures != null) { uiCultureInfo = GetCultureInfo( uiCultures, _options.SupportedUICultures, _options.FallBackToParentUICultures); } if (cultureInfo == null && uiCultureInfo == null) { continue; } if (cultureInfo == null && uiCultureInfo != null) { cultureInfo = _options.DefaultRequestCulture.Culture; } if (cultureInfo != null && uiCultureInfo == null) { uiCultureInfo = _options.DefaultRequestCulture.UICulture; } var result = new RequestCulture(cultureInfo, uiCultureInfo); if (result != null) { requestCulture = result; winningProvider = provider; break; } } } } context.Features.Set<IRequestCultureFeature>(new RequestCultureFeature(requestCulture, winningProvider)); SetCurrentThreadCulture(requestCulture); await _next(context); }
/// <summary> /// Creates a new <see cref="RequestCultureFeature"/> with the specified <see cref="Localization.RequestCulture"/>. /// </summary> /// <param name="requestCulture">The <see cref="Localization.RequestCulture"/>.</param> /// <param name="provider">The <see cref="IRequestCultureProvider"/>.</param> public RequestCultureFeature([NotNull] RequestCulture requestCulture, IRequestCultureProvider provider) { RequestCulture = requestCulture; Provider = provider; }