Log warnings when cultures specified by Request Culture Providers are unsupported

Fixes #372
This commit is contained in:
Pranav K 2017-08-28 14:31:56 -07:00
parent 7234a384f4
commit 41ae20525f
5 changed files with 98 additions and 41 deletions

View File

@ -13,6 +13,7 @@
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" /> <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" /> <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
namespace LocalizationSample namespace LocalizationSample
{ {
@ -154,6 +155,7 @@ $@"<!doctype html>
.Build(); .Build();
var host = new WebHostBuilder() var host = new WebHostBuilder()
.ConfigureLogging(factory => factory.AddConsole())
.UseKestrel() .UseKestrel()
.UseConfiguration(config) .UseConfiguration(config)
.UseIISIntegration() .UseIISIntegration()

View File

@ -15,6 +15,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" /> <PackageReference Include="Microsoft.AspNetCore.Http.Extensions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Options" /> <PackageReference Include="Microsoft.Extensions.Options" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,38 @@
// 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.Generic;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Localization
{
internal static class RequestCultureProviderLoggerExtensions
{
private static readonly Action<ILogger, string, IList<StringSegment>, Exception> _unsupportedCulture;
private static readonly Action<ILogger, string, IList<StringSegment>, Exception> _unsupportedUICulture;
static RequestCultureProviderLoggerExtensions()
{
_unsupportedCulture = LoggerMessage.Define<string, IList<StringSegment>>(
LogLevel.Warning,
1,
"{requestCultureProvider} returned the following unsupported cultures '{cultures}'.");
_unsupportedUICulture = LoggerMessage.Define<string, IList<StringSegment>>(
LogLevel.Warning,
2,
"{requestCultureProvider} returned the following unsupported cultures '{cultures}'.");
}
public static void UnsupportedCultures(this ILogger logger, string requestCultureProvider, IList<StringSegment> cultures)
{
_unsupportedCulture(logger, requestCultureProvider, cultures, null);
}
public static void UnsupportedUICultures(this ILogger logger, string requestCultureProvider, IList<StringSegment> uiCultures)
{
_unsupportedUICulture(logger, requestCultureProvider, uiCultures, null);
}
}
}

View File

@ -5,10 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
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.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
@ -24,6 +25,7 @@ namespace Microsoft.AspNetCore.Localization
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private readonly RequestLocalizationOptions _options; private readonly RequestLocalizationOptions _options;
private ILogger _logger;
/// <summary> /// <summary>
/// Creates a new <see cref="RequestLocalizationMiddleware"/>. /// Creates a new <see cref="RequestLocalizationMiddleware"/>.
@ -33,17 +35,12 @@ namespace Microsoft.AspNetCore.Localization
/// <see cref="RequestLocalizationMiddleware"/>.</param> /// <see cref="RequestLocalizationMiddleware"/>.</param>
public RequestLocalizationMiddleware(RequestDelegate next, IOptions<RequestLocalizationOptions> options) public RequestLocalizationMiddleware(RequestDelegate next, IOptions<RequestLocalizationOptions> options)
{ {
if (next == null)
{
throw new ArgumentNullException(nameof(next));
}
if (options == null) if (options == null)
{ {
throw new ArgumentNullException(nameof(options)); throw new ArgumentNullException(nameof(options));
} }
_next = next; _next = next ?? throw new ArgumentNullException(nameof(next));
_options = options.Value; _options = options.Value;
} }
@ -68,52 +65,65 @@ namespace Microsoft.AspNetCore.Localization
foreach (var provider in _options.RequestCultureProviders) foreach (var provider in _options.RequestCultureProviders)
{ {
var providerResultCulture = await provider.DetermineProviderCultureResult(context); var providerResultCulture = await provider.DetermineProviderCultureResult(context);
if (providerResultCulture != null) if (providerResultCulture == null)
{ {
var cultures = providerResultCulture.Cultures; continue;
var uiCultures = providerResultCulture.UICultures; }
var cultures = providerResultCulture.Cultures;
var uiCultures = providerResultCulture.UICultures;
CultureInfo cultureInfo = null; CultureInfo cultureInfo = null;
CultureInfo uiCultureInfo = null; CultureInfo uiCultureInfo = null;
if (_options.SupportedCultures != null) if (_options.SupportedCultures != null)
{
cultureInfo = GetCultureInfo(
cultures,
_options.SupportedCultures,
_options.FallBackToParentCultures);
if (cultureInfo == null)
{ {
cultureInfo = GetCultureInfo( EnsureLogger(context);
cultures, _logger?.UnsupportedCultures(provider.GetType().Name, cultures);
_options.SupportedCultures,
_options.FallBackToParentCultures);
} }
}
if (_options.SupportedUICultures != null) if (_options.SupportedUICultures != null)
{
uiCultureInfo = GetCultureInfo(
uiCultures,
_options.SupportedUICultures,
_options.FallBackToParentUICultures);
if (uiCultureInfo == null)
{ {
uiCultureInfo = GetCultureInfo( EnsureLogger(context);
uiCultures, _logger?.UnsupportedCultures(provider.GetType().Name, uiCultures);
_options.SupportedUICultures,
_options.FallBackToParentUICultures);
} }
}
if (cultureInfo == null && uiCultureInfo == null) if (cultureInfo == null && uiCultureInfo == null)
{ {
continue; continue;
} }
if (cultureInfo == null && uiCultureInfo != null) if (cultureInfo == null && uiCultureInfo != null)
{ {
cultureInfo = _options.DefaultRequestCulture.Culture; cultureInfo = _options.DefaultRequestCulture.Culture;
} }
if (cultureInfo != null && uiCultureInfo == null) if (cultureInfo != null && uiCultureInfo == null)
{ {
uiCultureInfo = _options.DefaultRequestCulture.UICulture; uiCultureInfo = _options.DefaultRequestCulture.UICulture;
} }
var result = new RequestCulture(cultureInfo, uiCultureInfo); var result = new RequestCulture(cultureInfo, uiCultureInfo);
if (result != null) if (result != null)
{ {
requestCulture = result; requestCulture = result;
winningProvider = provider; winningProvider = provider;
break; break;
}
} }
} }
} }
@ -125,6 +135,11 @@ namespace Microsoft.AspNetCore.Localization
await _next(context); await _next(context);
} }
private void EnsureLogger(HttpContext context)
{
_logger = _logger ?? context.RequestServices.GetService<ILogger<RequestLocalizationMiddleware>>();
}
private static void SetCurrentThreadCulture(RequestCulture requestCulture) private static void SetCurrentThreadCulture(RequestCulture requestCulture)
{ {
CultureInfo.CurrentCulture = requestCulture.Culture; CultureInfo.CurrentCulture = requestCulture.Culture;