From 0ac2a3f66a00bb2dfdb9e3d117a6e17329fcf5cc Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Thu, 22 Sep 2016 15:29:23 -0700 Subject: [PATCH] Use existing CultureInfo --- .../RequestLocalizationMiddleware.cs | 23 +++++++++- .../CultureInfoCache.cs | 3 +- .../StartupCustomCulturePreserved.cs | 42 +++++++++++++++++++ test/LocalizationWebsite/project.json | 1 + .../LocalizationTest.cs | 13 ++++++ 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 test/LocalizationWebsite/StartupCustomCulturePreserved.cs diff --git a/src/Microsoft.AspNetCore.Localization/RequestLocalizationMiddleware.cs b/src/Microsoft.AspNetCore.Localization/RequestLocalizationMiddleware.cs index 16103fd188..f9bc60a222 100644 --- a/src/Microsoft.AspNetCore.Localization/RequestLocalizationMiddleware.cs +++ b/src/Microsoft.AspNetCore.Localization/RequestLocalizationMiddleware.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Globalization; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Localization @@ -157,13 +157,32 @@ namespace Microsoft.AspNetCore.Localization return null; } + private static CultureInfo GetCultureInfo(string name, IList supportedCultures) + { + // Allow only known culture names as this API is called with input from users (HTTP requests) and + // creating CultureInfo objects is expensive and we don't want it to throw either. + if (name == null || supportedCultures == null) + { + return null; + } + var culture = supportedCultures.FirstOrDefault( + supportedCulture => string.Equals(supportedCulture.Name, name, StringComparison.OrdinalIgnoreCase)); + + if (culture == null) + { + return null; + } + + return CultureInfo.ReadOnly(culture); + } + private static CultureInfo GetCultureInfo( string cultureName, IList supportedCultures, bool fallbackToParentCultures, int currentDepth) { - var culture = CultureInfoCache.GetCultureInfo(cultureName, supportedCultures); + var culture = GetCultureInfo(cultureName, supportedCultures); if (culture == null && fallbackToParentCultures && currentDepth < MaxCultureFallbackDepth) { diff --git a/src/Microsoft.Extensions.Globalization.CultureInfoCache/CultureInfoCache.cs b/src/Microsoft.Extensions.Globalization.CultureInfoCache/CultureInfoCache.cs index a3ccb6d635..f9df733643 100644 --- a/src/Microsoft.Extensions.Globalization.CultureInfoCache/CultureInfoCache.cs +++ b/src/Microsoft.Extensions.Globalization.CultureInfoCache/CultureInfoCache.cs @@ -12,6 +12,7 @@ namespace Microsoft.Extensions.Globalization /// /// Provides read-only cached instances of . /// + [Obsolete("This type is obsolete and will be removed in a future version.")] public static class CultureInfoCache { private static readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); @@ -23,7 +24,7 @@ namespace Microsoft.Extensions.Globalization /// The culture name. /// The cultures supported by the application. /// - /// A read-only cached or null a match wasn't found in + /// A read-only cached or null if a match wasn't found in /// . /// public static CultureInfo GetCultureInfo(string name, IList supportedCultures) diff --git a/test/LocalizationWebsite/StartupCustomCulturePreserved.cs b/test/LocalizationWebsite/StartupCustomCulturePreserved.cs new file mode 100644 index 0000000000..778daa1387 --- /dev/null +++ b/test/LocalizationWebsite/StartupCustomCulturePreserved.cs @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Microsoft.Extensions.DependencyInjection; + +namespace LocalizationWebsite +{ + public class StartupCustomCulturePreserved + { + public void ConfigureServices(IServiceCollection services) + { + services.AddLocalization(); + } + + public void Configure( + IApplicationBuilder app) + { + app.UseRequestLocalization(new RequestLocalizationOptions + { + DefaultRequestCulture = new RequestCulture("en-US"), + SupportedCultures = new List() + { + new CultureInfo("en-US") { NumberFormat= { CurrencySymbol = "kr" } } + }, + SupportedUICultures = new List() + { + new CultureInfo("en-US") { NumberFormat= { CurrencySymbol = "kr" } } + } + }); + + app.Run(async (context) => + { + await context.Response.WriteAsync(10.ToString("C")); + }); + } + } +} diff --git a/test/LocalizationWebsite/project.json b/test/LocalizationWebsite/project.json index c44942c900..20a19a23c4 100644 --- a/test/LocalizationWebsite/project.json +++ b/test/LocalizationWebsite/project.json @@ -7,6 +7,7 @@ "dependencies": { "Microsoft.AspNetCore.Localization": "1.1.0-*", "Microsoft.AspNetCore.Server.Kestrel": "1.1.0-*", + "Microsoft.AspNetCore.Testing": "1.1.0-*", "Microsoft.Extensions.Configuration.CommandLine": "1.1.0-*", "Microsoft.Extensions.Localization": "1.1.0-*", "Microsoft.Extensions.Logging.Console": "1.1.0-*", diff --git a/test/Microsoft.AspNetCore.Localization.FunctionalTests/LocalizationTest.cs b/test/Microsoft.AspNetCore.Localization.FunctionalTests/LocalizationTest.cs index 6ae327ef15..8c4bc2004e 100644 --- a/test/Microsoft.AspNetCore.Localization.FunctionalTests/LocalizationTest.cs +++ b/test/Microsoft.AspNetCore.Localization.FunctionalTests/LocalizationTest.cs @@ -13,6 +13,19 @@ namespace Microsoft.AspNetCore.Localization.FunctionalTests { private static readonly string _applicationPath = Path.Combine("test", "LocalizationWebsite"); + [Fact] + public Task Localization_CustomCulture() + { + var testRunner = new TestRunner(_applicationPath); + return testRunner.RunTestAndVerifyResponse( + RuntimeFlavor.CoreClr, + RuntimeArchitecture.x64, + "http://localhost:5070", + "CustomCulturePreserved", + "en-US", + "kr10.00"); + } + [ConditionalTheory] [OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.MacOSX)]