Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Przez Hisham Bin Ateya, Damien Bowden, Bart Calixto i Nadeem Afana
Jednym z zadań lokalizowania aplikacji jest zawijanie zawartości lokalizowalnej za pomocą kodu, który ułatwia zastąpienie tej zawartości dla różnych kultur.
IStringLocalizer
IStringLocalizer zostały IStringLocalizer<T> zaprojektowane tak, aby zwiększyć produktywność podczas tworzenia zlokalizowanych aplikacji.
IStringLocalizer używa elementów ResourceManager i ResourceReader do udostępniania zasobów specyficznych dla kultury w czasie wykonywania. Interfejs zawiera indeksator i element IEnumerable do zwracania zlokalizowanych ciągów.
IStringLocalizer Program nie wymaga przechowywania domyślnych ciągów językowych w pliku zasobu. Możesz opracować aplikację przeznaczoną do lokalizacji i nie trzeba tworzyć plików zasobów na wczesnym etapie programowania.
W poniższym przykładzie kodu pokazano, jak opakować ciąg "About Title" (Informacje o tytule) dla lokalizacji.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers;
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
W poprzednim kodzie implementacja IStringLocalizer<T> pochodzi z wstrzykiwania zależności. Jeśli zlokalizowana wartość "About Title" (Informacje o tytule) nie zostanie znaleziona, zostanie zwrócony klucz indeksatora, czyli ciąg "About Title" (Informacje o tytule).
Możesz pozostawić domyślne ciągi literału języka w aplikacji i opakowować je w lokalizatorze, aby skoncentrować się na tworzeniu aplikacji. Tworzysz aplikację przy użyciu języka domyślnego i przygotowujesz ją do kroku lokalizacji bez uprzedniego utworzenia domyślnego pliku zasobu.
Alternatywnie możesz użyć tradycyjnego podejścia i podać klucz do pobrania domyślnego ciągu języka. Dla wielu deweloperów nowy przepływ pracy nie ma domyślnego pliku resx języka i po prostu zawijanie literałów ciągu może zmniejszyć obciążenie związane z lokalizacją aplikacji. Inni deweloperzy preferują tradycyjny przepływ pracy, ponieważ łatwiej jest pracować z długimi literałami ciągów i łatwiej aktualizować zlokalizowane ciągi.
IHtmlLocalizer
Użyj implementacji IHtmlLocalizer<TResource> dla zasobów zawierających kod HTML.
IHtmlLocalizer Koduje argumenty HTML sformatowane w ciągu zasobu, ale nie koduje kodu HTML samego ciągu zasobu. W poniższym wyróżnionym kodzie tylko wartość parametru name jest zakodowana w formacie HTML.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers;
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
UWAGA: Ogólnie rzecz biorąc, lokalizuj tylko tekst, a nie HTML.
IStringLocalizerFactory
Na najniższym poziomie IStringLocalizerFactory można pobrać z iniekcji zależności:
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
return View();
}
Powyższy kod demonstruje każdą z dwóch metod tworzenia fabryki.
Współdzielone zasoby
Zlokalizowane ciągi można podzielić na partycje według kontrolera lub obszaru albo mieć tylko jeden kontener. W przykładowej aplikacji klasa znacznika o nazwie SharedResource jest używana dla zasobów udostępnionych. Klasa znacznika nigdy nie jest wywoływana:
// Dummy class to group shared resources
namespace Localization;
public class SharedResource
{
}
W poniższym przykładzie InfoController używane są lokalizatory i SharedResource :
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
Wyświetlanie lokalizacji
Usługa IViewLocalizer udostępnia zlokalizowane ciągi dla widoku. Klasa ViewLocalizer implementuje ten interfejs i znajduje lokalizację zasobu ze ścieżki pliku widoku. Poniższy kod pokazuje, jak używać domyślnej implementacji programu IViewLocalizer:
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
Domyślna implementacja IViewLocalizer pliku zasobu znajduje plik na podstawie nazwy pliku widoku. Nie ma możliwości użycia globalnego pliku zasobów udostępnionych.
ViewLocalizer implementuje lokalizator przy użyciu metody IHtmlLocalizer, więc Razor nie koduje zlokalizowanego ciągu HTML. Parametry można sparametryzować, a IViewLocalizer kodowanie HTML parametrów, ale nie ciąg zasobu. Rozważmy następujące Razor znaczniki:
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Francuski plik zasobów może zawierać następujące wartości:
| Klawisz | Wartość |
|---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
Renderowany widok będzie zawierać znaczniki HTML z pliku zasobu.
Ogólnie rzecz biorąc, lokalizuj tylko tekst, a nie HTML.
Aby użyć udostępnionego pliku zasobów w widoku, należy wstrzyknąć IHtmlLocalizer<T>polecenie :
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
Lokalizacja danychAnnotations
Komunikaty o błędach DataAnnotations są zlokalizowane za pomocą polecenia IStringLocalizer<T>. Korzystając z opcji ResourcesPath = "Resources", komunikaty o błędach w pliku RegisterViewModel mogą być przechowywane w jednej z następujących ścieżek:
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
using System.ComponentModel.DataAnnotations;
namespace Localization.ViewModels.Account;
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.",
MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage =
"The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Atrybuty niewalidacyjne są zlokalizowane.
Jak używać jednego ciągu zasobu dla wielu klas
Poniższy kod pokazuje, jak używać jednego ciągu zasobu do sprawdzania poprawności atrybutów z wieloma klasami:
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
W poprzednim kodzie jest klasą odpowiadającą SharedResource, w którym są przechowywane komunikaty sprawdzania poprawności. W przypadku tego podejścia funkcja DataAnnotations używa SharedResourcetylko elementu , a nie zasobu dla każdej klasy.
Konfigurowanie usług lokalizacji
Usługi lokalizacji są konfigurowane w programie Program.cs:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization Dodaje usługi lokalizacji do kontenera usług, w tym implementacje dla
IStringLocalizer<T>iIStringLocalizerFactory. Powyższy kod ustawia również ścieżkę zasobów na "Zasoby".AddViewLocalization Dodaje obsługę zlokalizowanych plików widoku. W tym przykładzie lokalizacja widoku jest oparta na sufiksie pliku widoku. Na przykład "fr" w
Index.fr.cshtmlpliku.AddDataAnnotationsLocalization Dodaje obsługę zlokalizowanych
DataAnnotationskomunikatów weryfikacji za pośrednictwemIStringLocalizerabstrakcji.
Uwaga
Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Następne kroki
Lokalizowanie aplikacji obejmuje również następujące zadania:
- Udostępnianie zlokalizowanych zasobów dla języków i kultur obsługiwanych przez aplikację
- Implementowanie strategii wybierania języka/kultury dla każdego żądania
Dodatkowe zasoby
- Dostawca kultury adresu URL korzystający z oprogramowania pośredniczącego jako filtry w programie ASP.NET Core
- Globalne stosowanie elementu RouteDataRequest CultureProvider z oprogramowaniem pośredniczącym jako filtrami
- Globalizacja i lokalizacja w ASP.NET Core
- Udostępnianie zlokalizowanych zasobów dla języków i kultur w aplikacji ASP.NET Core
- Strategie wybierania języka i kultury w zlokalizowanej aplikacji ASP.NET Core
- Rozwiązywanie problemów z lokalizacją ASP.NET Core
- Globalizowanie i lokalizowanie aplikacji platformy .NET
- Localization.StarterWeb projektu użytego w artykule.
- Zasoby w plikach resx
- Lokalizacja i typy ogólne
Przez Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana i Hisham Bin Ateya
Jednym z zadań lokalizowania aplikacji jest zawijanie zawartości lokalizowalnej za pomocą kodu, który ułatwia zastąpienie tej zawartości dla różnych kultur.
IStringLocalizer
IStringLocalizer zostały IStringLocalizer<T> zaprojektowane tak, aby zwiększyć produktywność podczas tworzenia zlokalizowanych aplikacji.
IStringLocalizer używa elementów ResourceManager i ResourceReader do udostępniania zasobów specyficznych dla kultury w czasie wykonywania. Interfejs zawiera indeksator i element IEnumerable do zwracania zlokalizowanych ciągów.
IStringLocalizer Program nie wymaga przechowywania domyślnych ciągów językowych w pliku zasobu. Możesz opracować aplikację przeznaczoną do lokalizacji i nie trzeba tworzyć plików zasobów na wczesnym etapie programowania.
W poniższym przykładzie kodu pokazano, jak opakować ciąg "About Title" (Informacje o tytule) dla lokalizacji.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
}
W poprzednim kodzie implementacja IStringLocalizer<T> pochodzi z wstrzykiwania zależności. Jeśli zlokalizowana wartość "About Title" (Informacje o tytule) nie zostanie znaleziona, zostanie zwrócony klucz indeksatora, czyli ciąg "About Title" (Informacje o tytule).
Możesz pozostawić domyślne ciągi literału języka w aplikacji i opakowować je w lokalizatorze, aby skoncentrować się na tworzeniu aplikacji. Tworzysz aplikację przy użyciu języka domyślnego i przygotowujesz ją do kroku lokalizacji bez uprzedniego utworzenia domyślnego pliku zasobu.
Alternatywnie możesz użyć tradycyjnego podejścia i podać klucz do pobrania domyślnego ciągu języka. Dla wielu deweloperów nowy przepływ pracy nie ma domyślnego pliku resx języka i po prostu zawijanie literałów ciągu może zmniejszyć obciążenie związane z lokalizacją aplikacji. Inni deweloperzy preferują tradycyjny przepływ pracy, ponieważ łatwiej jest pracować z długimi literałami ciągów i łatwiej aktualizować zlokalizowane ciągi.
IHtmlLocalizer
Użyj implementacji IHtmlLocalizer<T> dla zasobów zawierających kod HTML.
IHtmlLocalizer Koduje argumenty HTML sformatowane w ciągu zasobu, ale nie koduje kodu HTML samego ciągu zasobu. W poniższym wyróżnionym kodzie tylko wartość parametru name jest zakodowana w formacie HTML.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers
{
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
Uwaga
Ogólnie rzecz biorąc, lokalizuj tylko tekst, a nie HTML.
IStringLocalizerFactory
Na najniższym poziomie można wydostać się IStringLocalizerFactory z wstrzykiwania zależności:
{
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
Powyższy kod demonstruje każdą z dwóch metod tworzenia fabryki.
Współdzielone zasoby
Zlokalizowane ciągi można podzielić na partycje według kontrolera lub obszaru albo mieć tylko jeden kontener. W przykładowej aplikacji fikcyjna klasa o nazwie SharedResource jest używana dla zasobów udostępnionych.
// Dummy class to group shared resources
namespace Localization
{
public class SharedResource
{
}
}
Niektórzy deweloperzy używają Startup klasy do przechowywania ciągów globalnych lub udostępnionych. W poniższym przykładzie InfoController używane są lokalizatory i SharedResource :
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
Wyświetlanie lokalizacji
Usługa IViewLocalizer udostępnia zlokalizowane ciągi dla widoku. Klasa ViewLocalizer implementuje ten interfejs i znajduje lokalizację zasobu ze ścieżki pliku widoku. Poniższy kod pokazuje, jak używać domyślnej implementacji programu IViewLocalizer:
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
Domyślna implementacja IViewLocalizer pliku zasobu znajduje plik na podstawie nazwy pliku widoku. Nie ma możliwości użycia globalnego pliku zasobów udostępnionych.
ViewLocalizer implementuje lokalizator przy użyciu metody IHtmlLocalizer, więc Razor nie koduje zlokalizowanego ciągu HTML. Parametry można sparametryzować, a IViewLocalizer kodowanie HTML parametrów, ale nie ciąg zasobu. Rozważmy następujące Razor znaczniki:
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Francuski plik zasobów może zawierać następujące wartości:
| Klawisz | Wartość |
|---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
Renderowany widok będzie zawierać znaczniki HTML z pliku zasobu.
Uwaga
Ogólnie rzecz biorąc, lokalizuj tylko tekst, a nie HTML.
Aby użyć udostępnionego pliku zasobów w widoku, należy wstrzyknąć IHtmlLocalizer<T>polecenie :
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
Lokalizacja danychAnnotations
Komunikaty o błędach DataAnnotations są zlokalizowane za pomocą polecenia IStringLocalizer<T>. Korzystając z opcji ResourcesPath = "Resources", komunikaty o błędach w pliku RegisterViewModel mogą być przechowywane w jednej z następujących ścieżek:
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
W ASP.NET Core MVC 1.1.0 lub nowszym atrybuty niewalidacyjne są zlokalizowane.
Jak używać jednego ciągu zasobu dla wielu klas
Poniższy kod pokazuje, jak używać jednego ciągu zasobu do sprawdzania poprawności atrybutów z wieloma klasami:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
W poprzednim kodzie jest klasą odpowiadającą SharedResource, w którym są przechowywane komunikaty sprawdzania poprawności. W przypadku tego podejścia funkcja DataAnnotations używa SharedResourcetylko elementu , a nie zasobu dla każdej klasy.
Konfigurowanie usług lokalizacji
Usługi lokalizacji są konfigurowane w metodzie Startup.ConfigureServices :
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalizationDodaje usługi lokalizacji do kontenera usług, w tym implementacje dlaIStringLocalizer<T>iIStringLocalizerFactory. Powyższy kod ustawia również ścieżkę zasobów na "Zasoby".AddViewLocalizationDodaje obsługę zlokalizowanych plików widoku. W tym przykładzie lokalizacja widoku jest oparta na sufiksie pliku widoku. Na przykład "fr" wIndex.fr.cshtmlpliku.AddDataAnnotationsLocalizationDodaje obsługę zlokalizowanychDataAnnotationskomunikatów weryfikacji za pośrednictwemIStringLocalizerabstrakcji.
Uwaga
Może nie być możliwe wprowadzenie przecinków dziesiętnych w polach dziesiętnych. Aby obsługiwać walidację jQuery dla ustawień regionalnych innych niż angielski, które używają przecinka (",") dla przecinka dziesiętnego i formatów dat innych niż angielskie stany USA, należy wykonać kroki w celu globalizacji aplikacji. Zobacz ten komentarz usługi GitHub 4076 , aby uzyskać instrukcje dotyczące dodawania przecinka dziesiętnego.
Następne kroki
Lokalizowanie aplikacji obejmuje również następujące zadania:
- Udostępnianie zlokalizowanych zasobów dla języków i kultur obsługiwanych przez aplikację
- Implementowanie strategii wybierania języka/kultury dla każdego żądania
Dodatkowe zasoby
- Globalizacja i lokalizacja w ASP.NET Core
- Udostępnianie zlokalizowanych zasobów dla języków i kultur w aplikacji ASP.NET Core
- Strategie wybierania języka i kultury w zlokalizowanej aplikacji ASP.NET Core
- Rozwiązywanie problemów z lokalizacją ASP.NET Core
- Globalizowanie i lokalizowanie aplikacji platformy .NET
- Localization.StarterWeb projektu użytego w artykule.
- Zasoby w plikach resx
- Lokalizacja i typy ogólne
ASP.NET Core