147 lines
5.6 KiB
Markdown
147 lines
5.6 KiB
Markdown
---
|
|
title: Localization Extensibility
|
|
author: hishamco
|
|
description: Learn how to extend the localization APIs in ASP.NET Core apps.
|
|
monikerRange: '>= aspnetcore-2.1'
|
|
ms.author: riande
|
|
ms.custom: mvc
|
|
ms.date: 08/03/2019
|
|
uid: fundamentals/localization-extensibility
|
|
---
|
|
# Localization Extensibility
|
|
|
|
[!INCLUDE[](~/includes/not-latest-version.md)]
|
|
|
|
By [Hisham Bin Ateya](https://github.com/hishamco)
|
|
|
|
This article:
|
|
|
|
* Lists the extensibility points on the localization APIs.
|
|
* Provides instructions on how to extend ASP.NET Core app localization.
|
|
|
|
## Extensible Points in Localization APIs
|
|
|
|
ASP.NET Core localization APIs are built to be extensible. Extensibility allows developers to customize the localization according to their needs. For instance, [OrchardCore](https://github.com/orchardCMS/OrchardCore/) has a `POStringLocalizer`. `POStringLocalizer` describes in detail using [Portable Object localization](xref:fundamentals/portable-object-localization) to use `PO` files to store localization resources.
|
|
|
|
This article lists the two main extensibility points that localization APIs provide:
|
|
|
|
* <xref:Microsoft.AspNetCore.Localization.RequestCultureProvider>
|
|
* <xref:Microsoft.Extensions.Localization.IStringLocalizer>
|
|
|
|
## Localization Culture Providers
|
|
|
|
ASP.NET Core localization APIs have four default providers that can determine the current culture of an executing request:
|
|
|
|
* <xref:Microsoft.AspNetCore.Localization.QueryStringRequestCultureProvider>
|
|
* <xref:Microsoft.AspNetCore.Localization.CookieRequestCultureProvider>
|
|
* <xref:Microsoft.AspNetCore.Localization.AcceptLanguageHeaderRequestCultureProvider>
|
|
* <xref:Microsoft.AspNetCore.Localization.CustomRequestCultureProvider>
|
|
|
|
The preceding providers are described in detail in the [Localization Middleware](xref:fundamentals/localization) documentation. If the default providers don't meet your needs, build a custom provider using one of the following approaches:
|
|
|
|
### Use CustomRequestCultureProvider
|
|
|
|
<xref:Microsoft.AspNetCore.Localization.CustomRequestCultureProvider> provides a custom <xref:Microsoft.AspNetCore.Localization.RequestCultureProvider> that uses a simple delegate to determine the current localization culture:
|
|
|
|
:::moniker range=">= aspnetcore-3.0"
|
|
|
|
```csharp
|
|
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
|
|
{
|
|
var currentCulture = "en";
|
|
var segments = context.Request.Path.Value.Split(new char[] { '/' },
|
|
StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (segments.Length > 1 && segments[0].Length == 2)
|
|
{
|
|
currentCulture = segments[0];
|
|
}
|
|
|
|
var requestCulture = new ProviderCultureResult(currentCulture);
|
|
|
|
return Task.FromResult(requestCulture);
|
|
}));
|
|
```
|
|
|
|
:::moniker-end
|
|
|
|
:::moniker range="< aspnetcore-3.0"
|
|
|
|
```csharp
|
|
options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
|
|
{
|
|
var currentCulture = "en";
|
|
var segments = context.Request.Path.Value.Split(new char[] { '/' },
|
|
StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
if (segments.Length > 1 && segments[0].Length == 2)
|
|
{
|
|
currentCulture = segments[0];
|
|
}
|
|
|
|
var requestCulture = new ProviderCultureResult(currentCulture);
|
|
|
|
return Task.FromResult(requestCulture);
|
|
}));
|
|
```
|
|
|
|
:::moniker-end
|
|
|
|
### Use a new implementation of RequestCultureProvider
|
|
|
|
A new implementation of <xref:Microsoft.AspNetCore.Localization.RequestCultureProvider> can be created that determines the request culture information from a custom source. For example, the custom source can be a configuration file or database.
|
|
|
|
The following example shows `AppSettingsRequestCultureProvider`, which extends the <xref:Microsoft.AspNetCore.Localization.RequestCultureProvider> to determine the request culture information from `appsettings.json`:
|
|
|
|
```csharp
|
|
public class AppSettingsRequestCultureProvider : RequestCultureProvider
|
|
{
|
|
public string CultureKey { get; set; } = "culture";
|
|
|
|
public string UICultureKey { get; set; } = "ui-culture";
|
|
|
|
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
|
|
{
|
|
if (httpContext == null)
|
|
{
|
|
throw new ArgumentNullException();
|
|
}
|
|
|
|
var configuration = httpContext.RequestServices.GetService<IConfigurationRoot>();
|
|
var culture = configuration[CultureKey];
|
|
var uiCulture = configuration[UICultureKey];
|
|
|
|
if (culture == null && uiCulture == null)
|
|
{
|
|
return Task.FromResult((ProviderCultureResult)null);
|
|
}
|
|
|
|
if (culture != null && uiCulture == null)
|
|
{
|
|
uiCulture = culture;
|
|
}
|
|
|
|
if (culture == null && uiCulture != null)
|
|
{
|
|
culture = uiCulture;
|
|
}
|
|
|
|
var providerResultCulture = new ProviderCultureResult(culture, uiCulture);
|
|
|
|
return Task.FromResult(providerResultCulture);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Localization resources
|
|
|
|
ASP.NET Core localization provides <xref:Microsoft.Extensions.Localization.ResourceManagerStringLocalizer>. <xref:Microsoft.Extensions.Localization.ResourceManagerStringLocalizer> is an implementation of <xref:Microsoft.Extensions.Localization.IStringLocalizer> that uses `resx` to store localization resources.
|
|
|
|
You aren't limited to using `resx` files. By implementing `IStringLocalizer`, any data source can be used.
|
|
|
|
The following example projects implement <xref:Microsoft.Extensions.Localization.IStringLocalizer>:
|
|
|
|
* [EFStringLocalizer](https://github.com/aspnet/Entropy/tree/master/samples/Localization.EntityFramework)
|
|
* [JsonStringLocalizer](https://github.com/hishamco/My.Extensions.Localization.Json)
|
|
* [SqlLocalizer](https://github.com/damienbod/AspNetCoreLocalization)
|