This commit is contained in:
Ryan Brandenburg 2016-09-22 15:29:23 -07:00
Родитель b2ef91df9f
Коммит 0ac2a3f66a
5 изменённых файлов: 79 добавлений и 3 удалений

Просмотреть файл

@ -4,11 +4,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Globalization;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Localization namespace Microsoft.AspNetCore.Localization
@ -157,13 +157,32 @@ namespace Microsoft.AspNetCore.Localization
return null; return null;
} }
private static CultureInfo GetCultureInfo(string name, IList<CultureInfo> 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( private static CultureInfo GetCultureInfo(
string cultureName, string cultureName,
IList<CultureInfo> supportedCultures, IList<CultureInfo> supportedCultures,
bool fallbackToParentCultures, bool fallbackToParentCultures,
int currentDepth) int currentDepth)
{ {
var culture = CultureInfoCache.GetCultureInfo(cultureName, supportedCultures); var culture = GetCultureInfo(cultureName, supportedCultures);
if (culture == null && fallbackToParentCultures && currentDepth < MaxCultureFallbackDepth) if (culture == null && fallbackToParentCultures && currentDepth < MaxCultureFallbackDepth)
{ {

Просмотреть файл

@ -12,6 +12,7 @@ namespace Microsoft.Extensions.Globalization
/// <summary> /// <summary>
/// Provides read-only cached instances of <see cref="CultureInfo"/>. /// Provides read-only cached instances of <see cref="CultureInfo"/>.
/// </summary> /// </summary>
[Obsolete("This type is obsolete and will be removed in a future version.")]
public static class CultureInfoCache public static class CultureInfoCache
{ {
private static readonly ConcurrentDictionary<string, CacheEntry> _cache = new ConcurrentDictionary<string, CacheEntry>(); private static readonly ConcurrentDictionary<string, CacheEntry> _cache = new ConcurrentDictionary<string, CacheEntry>();
@ -23,7 +24,7 @@ namespace Microsoft.Extensions.Globalization
/// <param name="name">The culture name.</param> /// <param name="name">The culture name.</param>
/// <param name="supportedCultures">The cultures supported by the application.</param> /// <param name="supportedCultures">The cultures supported by the application.</param>
/// <returns> /// <returns>
/// A read-only cached <see cref="CultureInfo"/> or <c>null</c> a match wasn't found in /// A read-only cached <see cref="CultureInfo"/> or <c>null</c> if a match wasn't found in
/// <paramref name="supportedCultures"/>. /// <paramref name="supportedCultures"/>.
/// </returns> /// </returns>
public static CultureInfo GetCultureInfo(string name, IList<CultureInfo> supportedCultures) public static CultureInfo GetCultureInfo(string name, IList<CultureInfo> supportedCultures)

Просмотреть файл

@ -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<CultureInfo>()
{
new CultureInfo("en-US") { NumberFormat= { CurrencySymbol = "kr" } }
},
SupportedUICultures = new List<CultureInfo>()
{
new CultureInfo("en-US") { NumberFormat= { CurrencySymbol = "kr" } }
}
});
app.Run(async (context) =>
{
await context.Response.WriteAsync(10.ToString("C"));
});
}
}
}

Просмотреть файл

@ -7,6 +7,7 @@
"dependencies": { "dependencies": {
"Microsoft.AspNetCore.Localization": "1.1.0-*", "Microsoft.AspNetCore.Localization": "1.1.0-*",
"Microsoft.AspNetCore.Server.Kestrel": "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.Configuration.CommandLine": "1.1.0-*",
"Microsoft.Extensions.Localization": "1.1.0-*", "Microsoft.Extensions.Localization": "1.1.0-*",
"Microsoft.Extensions.Logging.Console": "1.1.0-*", "Microsoft.Extensions.Logging.Console": "1.1.0-*",

Просмотреть файл

@ -13,6 +13,19 @@ namespace Microsoft.AspNetCore.Localization.FunctionalTests
{ {
private static readonly string _applicationPath = Path.Combine("test", "LocalizationWebsite"); 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] [ConditionalTheory]
[OSSkipCondition(OperatingSystems.Linux)] [OSSkipCondition(OperatingSystems.Linux)]
[OSSkipCondition(OperatingSystems.MacOSX)] [OSSkipCondition(OperatingSystems.MacOSX)]