Fix #111: Design changes to known/allowed culture list and cache
This commit is contained in:
parent
d25ad6607e
commit
636459a6f7
|
|
@ -19,8 +19,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
global.json = global.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CultureInfoGenerator", "src\CultureInfoGenerator\CultureInfoGenerator.xproj", "{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.Globalization.CultureInfoCache", "src\Microsoft.Extensions.Globalization.CultureInfoCache\Microsoft.Extensions.Globalization.CultureInfoCache.xproj", "{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{B723DB83-A670-4BCB-95FB-195361331AD2}"
|
||||
|
|
@ -55,10 +53,6 @@ Global
|
|||
{55D9501F-15B9-4339-A0AB-6082850E5FCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{55D9501F-15B9-4339-A0AB-6082850E5FCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{55D9501F-15B9-4339-A0AB-6082850E5FCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
@ -88,7 +82,6 @@ Global
|
|||
{23E3BC23-3464-4D9B-BF78-02CB2182BEF0} = {FB313677-BAB3-4E49-8CDB-4FA4A9564767}
|
||||
{A1FCF259-70F6-4605-AA2D-E4B356BE771A} = {FB313677-BAB3-4E49-8CDB-4FA4A9564767}
|
||||
{55D9501F-15B9-4339-A0AB-6082850E5FCE} = {79878809-8D1C-4BD4-BA99-F1F13FF96FD8}
|
||||
{BD22AE1C-6631-4DA6-874D-0DC0F803CEAB} = {FB313677-BAB3-4E49-8CDB-4FA4A9564767}
|
||||
{F3988D3A-A4C8-4FD7-BAFE-13E0D0A1659A} = {FB313677-BAB3-4E49-8CDB-4FA4A9564767}
|
||||
{287AD58D-DF34-4F16-8616-FD78FA1CADF9} = {B723DB83-A670-4BCB-95FB-195361331AD2}
|
||||
{19A2A931-5C60-47A0-816A-0DC9C4CE5736} = {B723DB83-A670-4BCB-95FB-195361331AD2}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
|
@ -24,16 +25,30 @@ namespace LocalizationSample
|
|||
var options = new RequestLocalizationOptions
|
||||
{
|
||||
// Set options here to change middleware behavior
|
||||
//SupportedCultures = new List<CultureInfo>
|
||||
//{
|
||||
// new CultureInfo("en-US"),
|
||||
// new CultureInfo("en-AU")
|
||||
//},
|
||||
//SupportedUICultures = new List<CultureInfo>
|
||||
//{
|
||||
// new CultureInfo("en-US"),
|
||||
// new CultureInfo("en-AU")
|
||||
//}
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("en-US"),
|
||||
new CultureInfo("en-AU"),
|
||||
new CultureInfo("en-GB"),
|
||||
new CultureInfo("es-ES"),
|
||||
new CultureInfo("ja-JP"),
|
||||
new CultureInfo("fr-FR"),
|
||||
new CultureInfo("zh"),
|
||||
new CultureInfo("zh-CN"),
|
||||
new CultureInfo("zh-CHT")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("en-US"),
|
||||
new CultureInfo("en-AU"),
|
||||
new CultureInfo("en-GB"),
|
||||
new CultureInfo("es-ES"),
|
||||
new CultureInfo("ja-JP"),
|
||||
new CultureInfo("fr-FR"),
|
||||
new CultureInfo("zh"),
|
||||
new CultureInfo("zh-CN"),
|
||||
new CultureInfo("zh-CHT")
|
||||
}
|
||||
};
|
||||
|
||||
// Optionally create an app-specific provider with just a delegate, e.g. look up user preference from DB.
|
||||
|
|
@ -43,7 +58,7 @@ namespace LocalizationSample
|
|||
|
||||
//}));
|
||||
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
|
@ -23,7 +25,7 @@ namespace Microsoft.AspNet.Localization
|
|||
public int MaximumAcceptLanguageHeaderValuesToTry { get; set; } = 3;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext)
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
|
|
@ -34,7 +36,7 @@ namespace Microsoft.AspNet.Localization
|
|||
|
||||
if (acceptLanguageHeader == null || acceptLanguageHeader.Count == 0)
|
||||
{
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
return Task.FromResult((ProviderCultureResult)null);
|
||||
}
|
||||
|
||||
var languages = acceptLanguageHeader.AsEnumerable();
|
||||
|
|
@ -47,30 +49,14 @@ namespace Microsoft.AspNet.Localization
|
|||
}
|
||||
|
||||
var orderedLanguages = languages.OrderByDescending(h => h, StringWithQualityHeaderValueComparer.QualityComparer)
|
||||
.ToList();
|
||||
.Select(x => x.Value).ToList();
|
||||
|
||||
foreach (var language in orderedLanguages)
|
||||
if (orderedLanguages.Any())
|
||||
{
|
||||
// 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?.Culture == culture)
|
||||
{
|
||||
return Task.FromResult(requestCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Task.FromResult(new ProviderCultureResult(orderedLanguages));
|
||||
}
|
||||
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
return Task.FromResult((ProviderCultureResult)null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Localization;
|
||||
|
||||
namespace Microsoft.AspNet.Builder
|
||||
|
|
@ -15,34 +16,46 @@ namespace Microsoft.AspNet.Builder
|
|||
/// 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="builder">The <see cref="IApplicationBuilder"/>.</param>
|
||||
/// <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 builder)
|
||||
public static IApplicationBuilder UseRequestLocalization(
|
||||
this IApplicationBuilder app,
|
||||
RequestCulture defaultRequestCulture)
|
||||
{
|
||||
if (builder == null)
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
if (defaultRequestCulture == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(defaultRequestCulture));
|
||||
}
|
||||
|
||||
var options = new RequestLocalizationOptions();
|
||||
|
||||
return UseRequestLocalization(builder, options);
|
||||
return UseRequestLocalization(app, options, defaultRequestCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="RequestLocalizationMiddleware"/> to automatically set culture information for
|
||||
/// requests based on information provided by the client.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/>.</param>
|
||||
/// <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 builder,
|
||||
RequestLocalizationOptions options)
|
||||
this IApplicationBuilder app,
|
||||
RequestLocalizationOptions options,
|
||||
RequestCulture defaultRequestCulture)
|
||||
{
|
||||
if (builder == null)
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
|
|
@ -50,7 +63,12 @@ namespace Microsoft.AspNet.Builder
|
|||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
return builder.UseMiddleware<RequestLocalizationMiddleware>(options);
|
||||
if (defaultRequestCulture == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(defaultRequestCulture));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<RequestLocalizationMiddleware>(options, defaultRequestCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Extensions.Globalization;
|
||||
|
|
@ -29,7 +31,7 @@ namespace Microsoft.AspNet.Localization
|
|||
public string CookieName { get; set; } = DefaultCookieName;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext)
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
|
|
@ -40,14 +42,12 @@ namespace Microsoft.AspNet.Localization
|
|||
|
||||
if (cookie == null)
|
||||
{
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
return Task.FromResult((ProviderCultureResult)null);
|
||||
}
|
||||
|
||||
var requestCulture = ParseCookieValue(cookie);
|
||||
var providerResultCulture = ParseCookieValue(cookie);
|
||||
|
||||
requestCulture = ValidateRequestCulture(requestCulture);
|
||||
|
||||
return Task.FromResult(requestCulture);
|
||||
return Task.FromResult(providerResultCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -75,7 +75,7 @@ namespace Microsoft.AspNet.Localization
|
|||
/// </summary>
|
||||
/// <param name="value">The cookie value to parse.</param>
|
||||
/// <returns>The <see cref="RequestCulture"/> or <c>null</c> if parsing fails.</returns>
|
||||
public static RequestCulture ParseCookieValue(string value)
|
||||
public static ProviderCultureResult ParseCookieValue(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
|
|
@ -100,15 +100,25 @@ namespace Microsoft.AspNet.Localization
|
|||
var cultureName = potentialCultureName.Substring(_culturePrefix.Length);
|
||||
var uiCultureName = potentialUICultureName.Substring(_uiCulturePrefix.Length);
|
||||
|
||||
var culture = CultureInfoCache.GetCultureInfo(cultureName);
|
||||
var uiCulture = CultureInfoCache.GetCultureInfo(uiCultureName);
|
||||
|
||||
if (culture == null || uiCulture == null)
|
||||
if (cultureName == null && uiCultureName == null)
|
||||
{
|
||||
// No values specified for either so no match
|
||||
return null;
|
||||
}
|
||||
|
||||
return new RequestCulture(culture, uiCulture);
|
||||
if (cultureName != null && uiCultureName == null)
|
||||
{
|
||||
// Value for culture but not for UI culture so default to culture value for both
|
||||
uiCultureName = cultureName;
|
||||
}
|
||||
|
||||
if (cultureName == null && uiCultureName != null)
|
||||
{
|
||||
// Value for UI culture but not for culture so default to UI culture value for both
|
||||
cultureName = uiCultureName;
|
||||
}
|
||||
|
||||
return new ProviderCultureResult(cultureName, uiCultureName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ namespace Microsoft.AspNet.Localization
|
|||
/// </summary>
|
||||
public class CustomRequestCultureProvider : RequestCultureProvider
|
||||
{
|
||||
private readonly Func<HttpContext, Task<RequestCulture>> _provider;
|
||||
private readonly Func<HttpContext, Task<ProviderCultureResult>> _provider;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CustomRequestCultureProvider"/> using the specified delegate.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider delegate.</param>
|
||||
public CustomRequestCultureProvider(Func<HttpContext, Task<RequestCulture>> provider)
|
||||
public CustomRequestCultureProvider(Func<HttpContext, Task<ProviderCultureResult>> provider)
|
||||
{
|
||||
if (provider == null)
|
||||
{
|
||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Localization
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext)
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// 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 System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
|
|
@ -16,9 +18,9 @@ namespace Microsoft.AspNet.Localization
|
|||
/// </summary>
|
||||
/// <param name="httpContext">The <see cref="HttpContext"/> for the request.</param>
|
||||
/// <returns>
|
||||
/// The determined <see cref="RequestCulture"/>.
|
||||
/// Returns <c>null</c> if the provider couldn't determine a <see cref="RequestCulture"/>.
|
||||
/// The determined <see cref="ProviderCultureResult"/>.
|
||||
/// Returns <c>null</c> if the provider couldn't determine a <see cref="ProviderCultureResult"/>.
|
||||
/// </returns>
|
||||
Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext);
|
||||
Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNet.Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// Details about the cultures obtained from <see cref="IRequestCultureProvider"/>.
|
||||
/// </summary>
|
||||
public class ProviderCultureResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ProviderCultureResult"/> object that has its <see cref="Cultures"/> and
|
||||
/// <see cref="UICultures"/> properties set to the same culture value.
|
||||
/// </summary>
|
||||
/// <param name="culture">The name of the culture to be used for formatting, text, i.e. language.</param>
|
||||
public ProviderCultureResult(string culture)
|
||||
: this(new List<string> { culture }, new List<string> { culture })
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ProviderCultureResult"/> object has its <see cref="Cultures"/> and
|
||||
/// <see cref="UICultures"/> properties set to the respective culture values provided.
|
||||
/// </summary>
|
||||
/// <param name="culture">The name of the culture to be used for formatting.</param>
|
||||
/// <param name="uiCulture"> The name of the ui culture to be used for text, i.e. language.</param>
|
||||
public ProviderCultureResult(string culture, string uiCulture)
|
||||
: this(new List<string> { culture }, new List<string> { uiCulture })
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ProviderCultureResult"/> object that has its <see cref="Cultures"/> and
|
||||
/// <see cref="UICultures"/> properties set to the same culture value.
|
||||
/// </summary>
|
||||
/// <param name="cultures">The list of cultures to be used for formatting, text, i.e. language.</param>
|
||||
public ProviderCultureResult(IList<string> cultures)
|
||||
: this(cultures, cultures)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ProviderCultureResult"/> object has its <see cref="Cultures"/> and
|
||||
/// <see cref="UICultures"/> properties set to the respective culture values provided.
|
||||
/// </summary>
|
||||
/// <param name="cultures">The list of cultures to be used for formatting.</param>
|
||||
/// <param name="uiCultures">The list of ui cultures to be used for text, i.e. language.</param>
|
||||
public ProviderCultureResult(IList<string> cultures, IList<string> uiCultures)
|
||||
{
|
||||
Cultures = cultures;
|
||||
UICultures = uiCultures;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of cultures to be used for formatting.
|
||||
/// </summary>
|
||||
public IList<string> Cultures { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of ui cultures to be used for text, i.e. language;
|
||||
/// </summary>
|
||||
public IList<string> UICultures { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Localization
|
|||
public string UIQueryStringKey { get; set; } = "ui-culture";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext)
|
||||
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Localization
|
|||
var request = httpContext.Request;
|
||||
if (!request.QueryString.HasValue)
|
||||
{
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
return Task.FromResult((ProviderCultureResult)null);
|
||||
}
|
||||
|
||||
string queryCulture = null;
|
||||
|
|
@ -56,7 +56,7 @@ namespace Microsoft.AspNet.Localization
|
|||
if (queryCulture == null && queryUICulture == null)
|
||||
{
|
||||
// No values specified for either so no match
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
return Task.FromResult((ProviderCultureResult)null);
|
||||
}
|
||||
|
||||
if (queryCulture != null && queryUICulture == null)
|
||||
|
|
@ -71,19 +71,9 @@ namespace Microsoft.AspNet.Localization
|
|||
queryCulture = queryUICulture;
|
||||
}
|
||||
|
||||
var culture = CultureInfoCache.GetCultureInfo(queryCulture);
|
||||
var uiCulture = CultureInfoCache.GetCultureInfo(queryUICulture);
|
||||
var providerResultCulture = new ProviderCultureResult(queryCulture, queryUICulture);
|
||||
|
||||
if (culture == null || uiCulture == null)
|
||||
{
|
||||
return Task.FromResult((RequestCulture)null);
|
||||
}
|
||||
|
||||
var requestCulture = new RequestCulture(culture, uiCulture);
|
||||
|
||||
requestCulture = ValidateRequestCulture(requestCulture);
|
||||
|
||||
return Task.FromResult(requestCulture);
|
||||
return Task.FromResult(providerResultCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,27 @@ namespace Microsoft.AspNet.Localization
|
|||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RequestCulture"/> object has its <see cref="Culture"/> and <see cref="UICulture"/>
|
||||
/// properties set to the same <see cref="CultureInfo"/> value.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture for the request.</param>
|
||||
public RequestCulture(string culture)
|
||||
: this(culture, culture)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RequestCulture"/> object has its <see cref="Culture"/> and <see cref="UICulture"/>
|
||||
/// properties set to the respective <see cref="CultureInfo"/> values provided.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture for the request to be used for formatting.</param>
|
||||
/// <param name="uiCulture">The culture for the request to be used for text, i.e. language.</param>
|
||||
public RequestCulture(string culture, string uiCulture)
|
||||
: this (new CultureInfo(culture), new CultureInfo(uiCulture))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RequestCulture"/> object has its <see cref="Culture"/> and <see cref="UICulture"/>
|
||||
/// properties set to the respective <see cref="CultureInfo"/> values provided.
|
||||
|
|
|
|||
|
|
@ -17,45 +17,7 @@ namespace Microsoft.AspNet.Localization
|
|||
public RequestLocalizationOptions Options { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract Task<RequestCulture> DetermineRequestCulture(HttpContext httpContext);
|
||||
public abstract Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext);
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the given <see cref="RequestCulture"/> is valid according to the currently configured.
|
||||
/// <see cref="RequestLocalizationOptions"/>.
|
||||
/// </summary>
|
||||
/// <param name="requestCulture">The <see cref="RequestCulture"/> to validate.</param>
|
||||
/// <returns>
|
||||
/// The original <see cref="RequestCulture"/> if it was valid, otherwise a new <see cref="RequestCulture"/>
|
||||
/// with values for <see cref="RequestCulture.Culture"/> and <see cref="RequestCulture.UICulture"/> that are
|
||||
/// valid for the current configuration, or <c>null</c> if neither <see cref="RequestCulture.Culture"/> or
|
||||
/// <see cref="RequestCulture.UICulture"/> were valid.
|
||||
/// </returns>
|
||||
protected RequestCulture ValidateRequestCulture(RequestCulture requestCulture)
|
||||
{
|
||||
if (requestCulture == null || Options == null)
|
||||
{
|
||||
return requestCulture;
|
||||
}
|
||||
|
||||
var result = requestCulture;
|
||||
|
||||
if (Options.SupportedCultures != null && !Options.SupportedCultures.Contains(result.Culture))
|
||||
{
|
||||
result = new RequestCulture(Options.DefaultRequestCulture.Culture, result.UICulture);
|
||||
}
|
||||
|
||||
if (Options.SupportedUICultures != null && !Options.SupportedUICultures.Contains(result.UICulture))
|
||||
{
|
||||
result = new RequestCulture(result.Culture, Options.DefaultRequestCulture.UICulture);
|
||||
}
|
||||
|
||||
if (requestCulture.Culture != result.Culture && requestCulture.UICulture != result.UICulture)
|
||||
{
|
||||
// Both cultures were invalid, just return null
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.Extensions.Globalization;
|
||||
|
||||
namespace Microsoft.AspNet.Localization
|
||||
{
|
||||
|
|
@ -19,13 +21,20 @@ namespace Microsoft.AspNet.Localization
|
|||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly RequestLocalizationOptions _options;
|
||||
private readonly RequestCulture _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>
|
||||
public RequestLocalizationMiddleware(RequestDelegate next, RequestLocalizationOptions options)
|
||||
/// <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)
|
||||
{
|
||||
|
|
@ -37,8 +46,14 @@ namespace Microsoft.AspNet.Localization
|
|||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if (defaultRequestCulture == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(defaultRequestCulture));
|
||||
}
|
||||
|
||||
_next = next;
|
||||
_options = options;
|
||||
_defaultRequestCulture = defaultRequestCulture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -53,8 +68,7 @@ namespace Microsoft.AspNet.Localization
|
|||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
var requestCulture = _options.DefaultRequestCulture ??
|
||||
new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);
|
||||
var requestCulture = _defaultRequestCulture;
|
||||
|
||||
IRequestCultureProvider winningProvider = null;
|
||||
|
||||
|
|
@ -62,12 +76,45 @@ namespace Microsoft.AspNet.Localization
|
|||
{
|
||||
foreach (var provider in _options.RequestCultureProviders)
|
||||
{
|
||||
var result = await provider.DetermineRequestCulture(context);
|
||||
if (result != null)
|
||||
var providerResultCulture = await provider.DetermineProviderCultureResult(context);
|
||||
if (providerResultCulture != null)
|
||||
{
|
||||
requestCulture = result;
|
||||
winningProvider = provider;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,5 +136,24 @@ namespace Microsoft.AspNet.Localization
|
|||
CultureInfo.CurrentUICulture = requestCulture.UICulture;
|
||||
#endif
|
||||
}
|
||||
|
||||
private CultureInfo GetCultureInfo(IList<string> cultures, IList<CultureInfo> supportedCultures)
|
||||
{
|
||||
foreach (var culture in cultures)
|
||||
{
|
||||
// Allow empty string values as they map to InvariantCulture, whereas null culture values will throw in
|
||||
// the CultureInfo ctor
|
||||
if (culture != null)
|
||||
{
|
||||
var cultureInfo = CultureInfoCache.GetCultureInfo(culture, supportedCultures);
|
||||
if (cultureInfo != null)
|
||||
{
|
||||
return cultureInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,6 @@ namespace Microsoft.AspNet.Localization
|
|||
/// </summary>
|
||||
public RequestLocalizationOptions()
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);
|
||||
|
||||
RequestCultureProviders = new List<IRequestCultureProvider>
|
||||
{
|
||||
new QueryStringRequestCultureProvider { Options = this },
|
||||
|
|
@ -27,14 +25,6 @@ namespace Microsoft.AspNet.Localization
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The default <see cref="RequestCulture"/> to use. This value will be used if none of the configured
|
||||
/// <see cref="IRequestCultureProvider"/> options result in a non-<c>null</c> result.
|
||||
/// Defaults to <see cref="RequestCulture.Culture"/> set to <see cref="CultureInfo.DefaultThreadCurrentCulture"/>
|
||||
/// and <see cref="RequestCulture.UICulture"/> set to <see cref="CultureInfo.DefaultThreadCurrentUICulture"/>.
|
||||
/// </summary>
|
||||
public RequestCulture DefaultRequestCulture { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The cultures supported by the application. If this value is non-<c>null</c>, the
|
||||
/// <see cref="RequestLocalizationMiddleware"/> will only set the current request culture to an entry in this
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
// 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;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.Extensions.Globalization
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides read-only cached instances of <see cref="CultureInfo"/>.
|
||||
/// </summary>
|
||||
public static partial class CultureInfoCache
|
||||
public static class CultureInfoCache
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, CacheEntry> _cache = new ConcurrentDictionary<string, CacheEntry>();
|
||||
|
||||
|
|
@ -18,15 +21,17 @@ namespace Microsoft.Extensions.Globalization
|
|||
/// <see cref="KnownCultureNames"/> will be used.
|
||||
/// </summary>
|
||||
/// <param name="name">The culture name.</param>
|
||||
/// <param name="supportedCultures">The cultures supported by the application.</param>
|
||||
/// <returns>
|
||||
/// A read-only cached <see cref="CultureInfo"/> or <c>null</c> a match wasn't found in
|
||||
/// <see cref="KnownCultureNames"/>.
|
||||
/// </returns>
|
||||
public static CultureInfo GetCultureInfo(string name)
|
||||
public 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 || !KnownCultureNames.Contains(name))
|
||||
if (name == null || supportedCultures == null ||
|
||||
!supportedCultures.Any(supportedCulture => string.Equals(supportedCulture.Name, name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,445 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// *************************** THIS FILE IS GENERATED BY A TOOL ***************************
|
||||
// To make changes to this file look at the CultureInfoGenerator project in this solution.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Extensions.Globalization
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a list of known culture names that can be used to create a <see cref="System.Globalization.CultureInfo"/>.
|
||||
/// </summary>
|
||||
public static partial class CultureInfoCache
|
||||
{
|
||||
/// <summary>
|
||||
/// This list of known cultures was generated by CultureInfoGenerator using .NET Framework 4.6 RC or later on
|
||||
/// Microsoft Windows NT 6.2.9200.0.
|
||||
/// As new versions of .NET Framework and Windows are released, this list should be regenerated to ensure it
|
||||
/// contains the latest culture names.
|
||||
/// </summary>
|
||||
public static readonly HashSet<string> KnownCultureNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"",
|
||||
"af",
|
||||
"af-ZA",
|
||||
"am",
|
||||
"am-ET",
|
||||
"ar",
|
||||
"ar-AE",
|
||||
"ar-BH",
|
||||
"ar-DZ",
|
||||
"ar-EG",
|
||||
"ar-IQ",
|
||||
"ar-JO",
|
||||
"ar-KW",
|
||||
"ar-LB",
|
||||
"ar-LY",
|
||||
"ar-MA",
|
||||
"ar-OM",
|
||||
"ar-QA",
|
||||
"ar-SA",
|
||||
"ar-SY",
|
||||
"ar-TN",
|
||||
"ar-YE",
|
||||
"arn",
|
||||
"arn-CL",
|
||||
"as",
|
||||
"as-IN",
|
||||
"az",
|
||||
"az-Cyrl",
|
||||
"az-Cyrl-AZ",
|
||||
"az-Latn",
|
||||
"az-Latn-AZ",
|
||||
"ba",
|
||||
"ba-RU",
|
||||
"be",
|
||||
"be-BY",
|
||||
"bg",
|
||||
"bg-BG",
|
||||
"bn",
|
||||
"bn-BD",
|
||||
"bn-IN",
|
||||
"bo",
|
||||
"bo-CN",
|
||||
"br",
|
||||
"br-FR",
|
||||
"bs",
|
||||
"bs-Cyrl",
|
||||
"bs-Cyrl-BA",
|
||||
"bs-Latn",
|
||||
"bs-Latn-BA",
|
||||
"ca",
|
||||
"ca-ES",
|
||||
"ca-ES-valencia",
|
||||
"chr",
|
||||
"chr-Cher",
|
||||
"chr-Cher-US",
|
||||
"co",
|
||||
"co-FR",
|
||||
"cs",
|
||||
"cs-CZ",
|
||||
"cy",
|
||||
"cy-GB",
|
||||
"da",
|
||||
"da-DK",
|
||||
"de",
|
||||
"de-AT",
|
||||
"de-CH",
|
||||
"de-DE",
|
||||
"de-LI",
|
||||
"de-LU",
|
||||
"dsb",
|
||||
"dsb-DE",
|
||||
"dv",
|
||||
"dv-MV",
|
||||
"el",
|
||||
"el-GR",
|
||||
"en",
|
||||
"en-029",
|
||||
"en-AU",
|
||||
"en-BZ",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-HK",
|
||||
"en-IE",
|
||||
"en-IN",
|
||||
"en-JM",
|
||||
"en-MY",
|
||||
"en-NZ",
|
||||
"en-PH",
|
||||
"en-SG",
|
||||
"en-TT",
|
||||
"en-US",
|
||||
"en-ZA",
|
||||
"en-ZW",
|
||||
"es",
|
||||
"es-419",
|
||||
"es-AR",
|
||||
"es-BO",
|
||||
"es-CL",
|
||||
"es-CO",
|
||||
"es-CR",
|
||||
"es-DO",
|
||||
"es-EC",
|
||||
"es-ES",
|
||||
"es-GT",
|
||||
"es-HN",
|
||||
"es-MX",
|
||||
"es-NI",
|
||||
"es-PA",
|
||||
"es-PE",
|
||||
"es-PR",
|
||||
"es-PY",
|
||||
"es-SV",
|
||||
"es-US",
|
||||
"es-UY",
|
||||
"es-VE",
|
||||
"et",
|
||||
"et-EE",
|
||||
"eu",
|
||||
"eu-ES",
|
||||
"fa",
|
||||
"fa-IR",
|
||||
"ff",
|
||||
"ff-Latn",
|
||||
"ff-Latn-SN",
|
||||
"fi",
|
||||
"fi-FI",
|
||||
"fil",
|
||||
"fil-PH",
|
||||
"fo",
|
||||
"fo-FO",
|
||||
"fr",
|
||||
"fr-BE",
|
||||
"fr-CA",
|
||||
"fr-CD",
|
||||
"fr-CH",
|
||||
"fr-CI",
|
||||
"fr-CM",
|
||||
"fr-FR",
|
||||
"fr-HT",
|
||||
"fr-LU",
|
||||
"fr-MA",
|
||||
"fr-MC",
|
||||
"fr-ML",
|
||||
"fr-RE",
|
||||
"fr-SN",
|
||||
"fy",
|
||||
"fy-NL",
|
||||
"ga",
|
||||
"ga-IE",
|
||||
"gd",
|
||||
"gd-GB",
|
||||
"gl",
|
||||
"gl-ES",
|
||||
"gn",
|
||||
"gn-PY",
|
||||
"gsw",
|
||||
"gsw-FR",
|
||||
"gu",
|
||||
"gu-IN",
|
||||
"ha",
|
||||
"ha-Latn",
|
||||
"ha-Latn-NG",
|
||||
"haw",
|
||||
"haw-US",
|
||||
"he",
|
||||
"he-IL",
|
||||
"hi",
|
||||
"hi-IN",
|
||||
"hr",
|
||||
"hr-BA",
|
||||
"hr-HR",
|
||||
"hsb",
|
||||
"hsb-DE",
|
||||
"hu",
|
||||
"hu-HU",
|
||||
"hy",
|
||||
"hy-AM",
|
||||
"id",
|
||||
"id-ID",
|
||||
"ig",
|
||||
"ig-NG",
|
||||
"ii",
|
||||
"ii-CN",
|
||||
"is",
|
||||
"is-IS",
|
||||
"it",
|
||||
"it-CH",
|
||||
"it-IT",
|
||||
"iu",
|
||||
"iu-Cans",
|
||||
"iu-Cans-CA",
|
||||
"iu-Latn",
|
||||
"iu-Latn-CA",
|
||||
"ja",
|
||||
"ja-JP",
|
||||
"jv",
|
||||
"jv-Latn",
|
||||
"jv-Latn-ID",
|
||||
"ka",
|
||||
"ka-GE",
|
||||
"kk",
|
||||
"kk-KZ",
|
||||
"kl",
|
||||
"kl-GL",
|
||||
"km",
|
||||
"km-KH",
|
||||
"kn",
|
||||
"kn-IN",
|
||||
"ko",
|
||||
"ko-KR",
|
||||
"kok",
|
||||
"kok-IN",
|
||||
"ku",
|
||||
"ku-Arab",
|
||||
"ku-Arab-IQ",
|
||||
"ky",
|
||||
"ky-KG",
|
||||
"lb",
|
||||
"lb-LU",
|
||||
"lo",
|
||||
"lo-LA",
|
||||
"lt",
|
||||
"lt-LT",
|
||||
"lv",
|
||||
"lv-LV",
|
||||
"mg",
|
||||
"mg-MG",
|
||||
"mi",
|
||||
"mi-NZ",
|
||||
"mk",
|
||||
"mk-MK",
|
||||
"ml",
|
||||
"ml-IN",
|
||||
"mn",
|
||||
"mn-Cyrl",
|
||||
"mn-MN",
|
||||
"mn-Mong",
|
||||
"mn-Mong-CN",
|
||||
"mn-Mong-MN",
|
||||
"moh",
|
||||
"moh-CA",
|
||||
"mr",
|
||||
"mr-IN",
|
||||
"ms",
|
||||
"ms-BN",
|
||||
"ms-MY",
|
||||
"mt",
|
||||
"mt-MT",
|
||||
"my",
|
||||
"my-MM",
|
||||
"nb",
|
||||
"nb-NO",
|
||||
"ne",
|
||||
"ne-IN",
|
||||
"ne-NP",
|
||||
"nl",
|
||||
"nl-BE",
|
||||
"nl-NL",
|
||||
"nn",
|
||||
"nn-NO",
|
||||
"no",
|
||||
"nqo",
|
||||
"nqo-GN",
|
||||
"nso",
|
||||
"nso-ZA",
|
||||
"oc",
|
||||
"oc-FR",
|
||||
"om",
|
||||
"om-ET",
|
||||
"or",
|
||||
"or-IN",
|
||||
"pa",
|
||||
"pa-Arab",
|
||||
"pa-Arab-PK",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
"pl-PL",
|
||||
"prs",
|
||||
"prs-AF",
|
||||
"ps",
|
||||
"ps-AF",
|
||||
"pt",
|
||||
"pt-AO",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"qut",
|
||||
"qut-GT",
|
||||
"quz",
|
||||
"quz-BO",
|
||||
"quz-EC",
|
||||
"quz-PE",
|
||||
"rm",
|
||||
"rm-CH",
|
||||
"ro",
|
||||
"ro-MD",
|
||||
"ro-RO",
|
||||
"ru",
|
||||
"ru-RU",
|
||||
"rw",
|
||||
"rw-RW",
|
||||
"sa",
|
||||
"sa-IN",
|
||||
"sah",
|
||||
"sah-RU",
|
||||
"sd",
|
||||
"sd-Arab",
|
||||
"sd-Arab-PK",
|
||||
"se",
|
||||
"se-FI",
|
||||
"se-NO",
|
||||
"se-SE",
|
||||
"si",
|
||||
"si-LK",
|
||||
"sk",
|
||||
"sk-SK",
|
||||
"sl",
|
||||
"sl-SI",
|
||||
"sma",
|
||||
"sma-NO",
|
||||
"sma-SE",
|
||||
"smj",
|
||||
"smj-NO",
|
||||
"smj-SE",
|
||||
"smn",
|
||||
"smn-FI",
|
||||
"sms",
|
||||
"sms-FI",
|
||||
"sn",
|
||||
"sn-Latn",
|
||||
"sn-Latn-ZW",
|
||||
"so",
|
||||
"so-SO",
|
||||
"sq",
|
||||
"sq-AL",
|
||||
"sr",
|
||||
"sr-Cyrl",
|
||||
"sr-Cyrl-BA",
|
||||
"sr-Cyrl-CS",
|
||||
"sr-Cyrl-ME",
|
||||
"sr-Cyrl-RS",
|
||||
"sr-Latn",
|
||||
"sr-Latn-BA",
|
||||
"sr-Latn-CS",
|
||||
"sr-Latn-ME",
|
||||
"sr-Latn-RS",
|
||||
"st",
|
||||
"st-ZA",
|
||||
"sv",
|
||||
"sv-FI",
|
||||
"sv-SE",
|
||||
"sw",
|
||||
"sw-KE",
|
||||
"syr",
|
||||
"syr-SY",
|
||||
"ta",
|
||||
"ta-IN",
|
||||
"ta-LK",
|
||||
"te",
|
||||
"te-IN",
|
||||
"tg",
|
||||
"tg-Cyrl",
|
||||
"tg-Cyrl-TJ",
|
||||
"th",
|
||||
"th-TH",
|
||||
"ti",
|
||||
"ti-ER",
|
||||
"ti-ET",
|
||||
"tk",
|
||||
"tk-TM",
|
||||
"tn",
|
||||
"tn-BW",
|
||||
"tn-ZA",
|
||||
"tr",
|
||||
"tr-TR",
|
||||
"ts",
|
||||
"ts-ZA",
|
||||
"tt",
|
||||
"tt-RU",
|
||||
"tzm",
|
||||
"tzm-Latn",
|
||||
"tzm-Latn-DZ",
|
||||
"tzm-Tfng",
|
||||
"tzm-Tfng-MA",
|
||||
"ug",
|
||||
"ug-CN",
|
||||
"uk",
|
||||
"uk-UA",
|
||||
"ur",
|
||||
"ur-IN",
|
||||
"ur-PK",
|
||||
"uz",
|
||||
"uz-Cyrl",
|
||||
"uz-Cyrl-UZ",
|
||||
"uz-Latn",
|
||||
"uz-Latn-UZ",
|
||||
"vi",
|
||||
"vi-VN",
|
||||
"wo",
|
||||
"wo-SN",
|
||||
"xh",
|
||||
"xh-ZA",
|
||||
"yo",
|
||||
"yo-NG",
|
||||
"zgh",
|
||||
"zgh-Tfng",
|
||||
"zgh-Tfng-MA",
|
||||
"zh",
|
||||
"zh-CN",
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
"zh-HK",
|
||||
"zh-MO",
|
||||
"zh-SG",
|
||||
"zh-TW",
|
||||
"zu",
|
||||
"zu-ZA",
|
||||
"zh-CHS",
|
||||
"zh-CHT"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
// 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 LocalizationWebsite.Models;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Localization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -26,7 +29,19 @@ namespace LocalizationWebsite
|
|||
{
|
||||
loggerFactory.AddConsole(minLevel: LogLevel.Warning);
|
||||
|
||||
app.UseRequestLocalization();
|
||||
var options = new RequestLocalizationOptions
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>()
|
||||
{
|
||||
new CultureInfo("fr-FR")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>()
|
||||
{
|
||||
new CultureInfo("fr-FR")
|
||||
}
|
||||
};
|
||||
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
|
||||
var stringLocalizer = stringLocalizerFactory.Create("Test", location: null);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
// 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 LocalizationWebsite.Models;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Localization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -26,7 +29,19 @@ namespace LocalizationWebsite
|
|||
{
|
||||
loggerFactory.AddConsole(minLevel: LogLevel.Warning);
|
||||
|
||||
app.UseRequestLocalization();
|
||||
var options = new RequestLocalizationOptions
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>()
|
||||
{
|
||||
new CultureInfo("fr-FR")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>()
|
||||
{
|
||||
new CultureInfo("fr-FR")
|
||||
}
|
||||
};
|
||||
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
|
||||
var stringLocalizer = stringLocalizerFactory.Create("Test", location: null);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.Extensions.Localization.Tests
|
||||
{
|
||||
public class AccessLanguageHeaderRequestCultureProviderTest
|
||||
public class AcceptLanguageHeaderRequestCultureProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public async void GetFallbackLanguage_ReturnsFirstNonNullCultureFromSupportedCultureList()
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
new CultureInfo("en-US")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -52,14 +52,13 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
var options = new RequestLocalizationOptions
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture(new CultureInfo("fr-FR")),
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA"),
|
||||
new CultureInfo("en-US")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("fr-FR"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -83,14 +82,13 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
var options = new RequestLocalizationOptions
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture(new CultureInfo("fr-FR")),
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA"),
|
||||
new CultureInfo("af-ZA")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("fr-FR"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -124,7 +122,7 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
new CultureInfo("ar-YE")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// 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 System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
|
|
@ -19,11 +20,21 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
var provider = new CookieRequestCultureProvider();
|
||||
provider.CookieName = "Preferences";
|
||||
options.RequestCultureProviders.Insert(0, provider);
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -48,16 +59,26 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
var provider = new CookieRequestCultureProvider();
|
||||
provider.CookieName = "Preferences";
|
||||
options.RequestCultureProviders.Insert(0, provider);
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
var requestCulture = requestCultureFeature.RequestCulture;
|
||||
Assert.Equal(options.DefaultRequestCulture.Culture.Name, requestCulture.Culture.Name);
|
||||
Assert.Equal("en-US", requestCulture.Culture.Name);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
}))
|
||||
|
|
@ -73,16 +94,26 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
var provider = new CookieRequestCultureProvider();
|
||||
provider.CookieName = "Preferences";
|
||||
options.RequestCultureProviders.Insert(0, provider);
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
var requestCulture = requestCultureFeature.RequestCulture;
|
||||
Assert.Equal(options.DefaultRequestCulture.Culture.Name, requestCulture.Culture.Name);
|
||||
Assert.Equal("en-US", requestCulture.Culture.Name);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
|
|
@ -21,14 +22,24 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar")
|
||||
}
|
||||
};
|
||||
options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context =>
|
||||
{
|
||||
var culture = GetCultureInfoFromUrl(context);
|
||||
var requestCulture = new RequestCulture(culture);
|
||||
var culture = GetCultureInfoFromUrl(context, options.SupportedCultures);
|
||||
var requestCulture = new ProviderCultureResult(culture);
|
||||
return Task.FromResult(requestCulture);
|
||||
}));
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -43,18 +54,16 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
}
|
||||
}
|
||||
|
||||
private CultureInfo GetCultureInfoFromUrl(HttpContext context)
|
||||
private string GetCultureInfoFromUrl(HttpContext context, IList<CultureInfo> supportedCultures)
|
||||
{
|
||||
var currentCulture = "en";
|
||||
var segments = context.Request.Path.Value.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (segments.Length > 1 && segments[0].Length == 2)
|
||||
{
|
||||
if (CultureInfoCache.KnownCultureNames.Contains(segments[0]))
|
||||
currentCulture = segments[0];
|
||||
else
|
||||
throw new InvalidOperationException($"The '{segments[0]}' is invalid culture name.");
|
||||
currentCulture = segments[0];
|
||||
}
|
||||
return CultureInfoCache.GetCultureInfo(currentCulture);
|
||||
|
||||
return currentCulture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
// 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 System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
|
|
@ -17,8 +19,19 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-YE")
|
||||
}
|
||||
};
|
||||
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -40,13 +53,13 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
var requestCulture = requestCultureFeature.RequestCulture;
|
||||
Assert.Equal(options.DefaultRequestCulture.Culture.Name, requestCulture.Culture.Name);
|
||||
Assert.Equal(options.DefaultRequestCulture.UICulture.Name, requestCulture.UICulture.Name);
|
||||
Assert.Equal("en-US", requestCulture.Culture.Name);
|
||||
Assert.Equal("en-US", requestCulture.UICulture.Name);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
}))
|
||||
|
|
@ -57,17 +70,27 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async void GetDefaultCultureInfoIfCultureIsInvalid()
|
||||
public async void GetDefaultCultureInfoIfCultureIsInSupportedCultureList()
|
||||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
var requestCulture = requestCultureFeature.RequestCulture;
|
||||
Assert.Equal(options.DefaultRequestCulture.Culture.Name, requestCulture.Culture.Name);
|
||||
Assert.Equal("en-US", requestCulture.Culture.Name);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
}))
|
||||
|
|
@ -78,17 +101,27 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public async void GetDefaultCultureInfoIfUICultureIsInvalid()
|
||||
public async void GetDefaultCultureInfoIfUICultureIsNotInSupportedList()
|
||||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
var requestCulture = requestCultureFeature.RequestCulture;
|
||||
Assert.Equal(options.DefaultRequestCulture.UICulture.Name, requestCulture.UICulture.Name);
|
||||
Assert.Equal("en-US", requestCulture.UICulture.Name);
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
}))
|
||||
|
|
@ -103,8 +136,18 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -125,8 +168,18 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
app.UseRequestLocalization(options);
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
}
|
||||
};
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -147,12 +200,22 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-SA")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("ar-YE")
|
||||
}
|
||||
};
|
||||
var provider = new QueryStringRequestCultureProvider();
|
||||
provider.QueryStringKey = "c";
|
||||
provider.UIQueryStringKey = "uic";
|
||||
options.RequestCultureProviders.Insert(0, provider);
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
@ -173,12 +236,22 @@ namespace Microsoft.Extensions.Localization.Tests
|
|||
{
|
||||
using (var server = TestServer.Create(app =>
|
||||
{
|
||||
var options = new RequestLocalizationOptions();
|
||||
var options = new RequestLocalizationOptions()
|
||||
{
|
||||
SupportedCultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("FR")
|
||||
},
|
||||
SupportedUICultures = new List<CultureInfo>
|
||||
{
|
||||
new CultureInfo("FR")
|
||||
}
|
||||
};
|
||||
var provider = new QueryStringRequestCultureProvider();
|
||||
provider.QueryStringKey = "c";
|
||||
provider.UIQueryStringKey = "uic";
|
||||
options.RequestCultureProviders.Insert(0, provider);
|
||||
app.UseRequestLocalization(options);
|
||||
app.UseRequestLocalization(options, defaultRequestCulture: new RequestCulture("en-US"));
|
||||
app.Run(context =>
|
||||
{
|
||||
var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue