Delen via


Globalisering en lokalisatie in ASP.NET Core

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikel voor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikel voor de huidige release.

Door Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana en Hisham Bin Ateya

Met een meertalige website kan een website een breder publiek bereiken. ASP.NET Core biedt services en middleware voor lokalisatie in verschillende talen en culturen.

Zie Blazor de globalisatie- en lokalisatierichtlijnen voor ASP.NET Core Blazor, die de richtlijnen in dit artikel aanvullen of vervangen.

Voorwaarden

  • Globalisatie (G11N): het proces voor het maken van een app ondersteunt verschillende talen en regio's. De afkorting komt uit de eerste en laatste letters en het aantal letters ertussen.
  • Lokalisatie (L10N): het proces voor het aanpassen van een geglobaliseerde app voor specifieke talen en regio's.
  • Internationalisatie (I18N): Zowel globalisering als lokalisatie.
  • Cultuur: Een taal en, optioneel, een regio.
  • Neutrale cultuur: een cultuur met een opgegeven taal, maar geen regio (bijvoorbeeld "en", "es").
  • Specifieke cultuur: Een cultuur met een opgegeven taal en regio (bijvoorbeeld "en-US", "en-GB", "es-CL").
  • Bovenliggende cultuur: De neutrale cultuur die een specifieke cultuur bevat (bijvoorbeeld "en" is de bovenliggende cultuur van "en-US" en "en-GB").
  • Taalinstelling: Een taalinstelling is hetzelfde als een taalomgeving.

Taal- en land-/regiocodes

De RFC 4646-indeling voor de cultuurnaam is <language code>-<country/region code>, waarbij <language code> de taal wordt geïdentificeerd en <country/region code> de subcultuur wordt geïdentificeerd. Bijvoorbeeld voor es-CL Spaans (Chili), voor Engels (Verenigde Staten) en-US en en-AU voor Engels (Australië). RFC 4646 is een combinatie van een ISO 639-cultuurcode met twee letters die is gekoppeld aan een taal en een ISO 3166-subcultuurcode met twee letters die zijn gekoppeld aan een land of regio. Zie System.Globalization.CultureInfo voor meer informatie.

Taken voor het lokaliseren van een app

Het globaliseren en lokaliseren van een app omvat de volgende taken:

Voorbeeldcode bekijken of downloaden (hoe download je)

Aanvullende bronnen

Door Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana en Hisham Bin Ateya

Met een meertalige website kan een website een breder publiek bereiken. ASP.NET Core biedt services en middleware voor lokalisatie in verschillende talen en culturen.

Voorwaarden

  • Globalisatie (G11N): het proces voor het maken van een app ondersteunt verschillende talen en regio's. De afkorting komt uit de eerste en laatste letters en het aantal letters ertussen.
  • Lokalisatie (L10N): het proces voor het aanpassen van een geglobaliseerde app voor specifieke talen en regio's.
  • Internationalisatie (I18N): Zowel globalisering als lokalisatie.
  • Cultuur: Een taal en, optioneel, een regio.
  • Neutrale cultuur: een cultuur met een opgegeven taal, maar geen regio (bijvoorbeeld "en", "es").
  • Specifieke cultuur: Een cultuur met een opgegeven taal en regio (bijvoorbeeld "en-US", "en-GB", "es-CL").
  • Bovenliggende cultuur: De neutrale cultuur die een specifieke cultuur bevat (bijvoorbeeld "en" is de bovenliggende cultuur van "en-US" en "en-GB").
  • Taalinstelling: Een taalinstelling is hetzelfde als een taalomgeving.

Taal- en land-/regiocodes

De RFC 4646-indeling voor de cultuurnaam is <language code>-<country/region code>, waarbij <language code> de taal wordt geïdentificeerd en <country/region code> de subcultuur wordt geïdentificeerd. Bijvoorbeeld voor es-CL Spaans (Chili), voor Engels (Verenigde Staten) en-US en en-AU voor Engels (Australië). RFC 4646 is een combinatie van een ISO 639-cultuurcode met twee letters die is gekoppeld aan een taal en een ISO 3166-subcultuurcode met twee letters die zijn gekoppeld aan een land of regio. Zie System.Globalization.CultureInfo voor meer informatie.

Taken voor het lokaliseren van een app

Het globaliseren en lokaliseren van een app omvat de volgende taken:

Voorbeeldcode bekijken of downloaden (hoe download je)

Aanvullende bronnen

Door Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana en Hisham Bin Ateya

Met een meertalige website kan de site een breder publiek bereiken. ASP.NET Core biedt services en middleware voor lokalisatie in verschillende talen en culturen.

Internationalisatie omvat System.Globalization en lokalisatie. Globalisatie is het proces van het ontwerpen van apps die verschillende culturen ondersteunen. Globalisatie voegt ondersteuning toe voor invoer, weergave en uitvoer van een gedefinieerde set taalscripts die betrekking hebben op specifieke geografische gebieden.

Lokalisatie is het proces van het aanpassen van een geglobaliseerde app, die u al hebt verwerkt voor lokalisatie, naar een bepaalde cultuur/landinstelling. Zie Globalisatie- en lokalisatietermen aan het einde van dit document voor meer informatie.

App-lokalisatie omvat het volgende:

  1. De inhoud van de app lokaliseren
  2. Gelokaliseerde resources bieden voor de talen en culturen die u ondersteunt
  3. Een strategie implementeren om de taal/cultuur voor elke aanvraag te selecteren

Voorbeeldcode bekijken of downloaden (hoe download je)

De app-inhoud lokaliseren

IStringLocalizer en IStringLocalizer<T> zijn ontworpen om de productiviteit te verbeteren bij het ontwikkelen van gelokaliseerde apps. IStringLocalizer maakt gebruik van de ResourceManager en ResourceReader om cultuurspecifieke resources tijdens runtime te bieden. De interface heeft een indexeerfunctie en een IEnumerable voor het retourneren van gelokaliseerde tekenreeksen. IStringLocalizer vereist geen opslag van de standaardtaaltekenreeksen in een resourcebestand. U kunt een app ontwikkelen die is gericht op lokalisatie en u hoeft geen resourcebestanden vroeg in ontwikkeling te maken. In de onderstaande code ziet u hoe u de tekenreeks 'Over titel' verpakt voor lokalisatie.

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"];
        }
    }
}

In de voorgaande code is de IStringLocalizer<T> implementatie afkomstig van afhankelijkheidsinjectie. Als de gelokaliseerde waarde van 'Over Titel' niet wordt gevonden, wordt de indexeersleutel geretourneerd, namelijk de tekenreeks 'Over Titel'. U kunt de letterlijke tekenreeksen voor de standaardtaal in de app laten staan en in de localizer verpakken, zodat u zich kunt richten op het ontwikkelen van de app. U ontwikkelt uw app met uw standaardtaal en bereidt deze voor op de lokalisatiestap zonder eerst een standaardresourcebestand te maken. U kunt ook de traditionele benadering gebruiken en een sleutel opgeven om de standaardtaaltekenreeks op te halen. Voor veel ontwikkelaars kan de nieuwe werkstroom van het niet hebben van een standaardtaal .resx-bestand en het eenvoudig verpakken van de letterlijke tekenreeksen de overhead van het lokaliseren van een app verminderen. Andere ontwikkelaars geven de voorkeur aan de traditionele werkstroom, omdat het eenvoudiger is om te werken met langere letterlijke tekenreeksen en om gelokaliseerde tekenreeksen gemakkelijker bij te werken.

Gebruik de IHtmlLocalizer<T> implementatie voor resources die HTML bevatten. IHtmlLocalizer HTML codeert argumenten die zijn opgemaakt in de resourcetekenreeks, maar codeert de resourcetekenreeks zelf niet. In het onderstaande voorbeeld is alleen de waarde van name de parameter gecodeerd met 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();
        }

Opmerking

Over het algemeen lokaliseer alleen tekst, niet HTML.

Op het laagste niveau kunt u de IStringLocalizerFactory uitschakelen:

{
    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."];

In de bovenstaande code ziet u elk van de twee methoden voor het maken van fabrieken.

U kunt uw gelokaliseerde tekenreeksen partitioneren per controller, gebied of domein, of slechts één container gebruiken. In de voorbeeld-app wordt een dummy-klasse met de naam SharedResource gebruikt voor gedeelde resources.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Sommige ontwikkelaars gebruiken de Startup klasse om globale of gedeelde tekenreeksen te bevatten. In het onderstaande voorbeeld worden de InfoController en de SharedResource lokalisaties gebruikt:

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;
    }

Lokalisatie weergeven

De IViewLocalizer service biedt gelokaliseerde tekenreeksen voor een weergave. De ViewLocalizer klasse implementeert deze interface en zoekt de resourcelocatie op basis van het pad van het weergavebestand. De volgende code laat zien hoe u de standaardimplementatie van IViewLocalizer kunt gebruiken.

@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>

De standaard implementatie van IViewLocalizer vindt het resourcebestand op basis van de bestandsnaam van de weergave. Er is geen optie om een globaal gedeeld resourcebestand te gebruiken. ViewLocalizer implementeert de localizer met behulp van IHtmlLocalizer, dus Razor codeer de gelokaliseerde tekenreeks niet in HTML. U kunt bronreeksen parameteriseren en IViewLocalizer zal de parameters HTML encoderen, maar niet de bronreeks. Houd rekening met de volgende Razor markeringen:

@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]

Een Frans resourcebestand kan het volgende bevatten:

Sleutelcode Waarde
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

De weergegeven weergave bevat de HTML-opmaak uit het resourcebestand.

Opmerking

Over het algemeen lokaliseer alleen tekst, niet HTML.

Als u een gedeeld resourcebestand in een weergave wilt gebruiken, injecteert u IHtmlLocalizer<T>.

@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>

Lokalisatie van DataAnnotations

DataAnnotations-foutberichten worden gelokaliseerd met IStringLocalizer<T>. Met behulp van de optie ResourcesPath = "Resources"kunnen de foutberichten RegisterViewModel worden opgeslagen in een van de volgende paden:

  • 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; }
}

Niet-validerende attributen worden gelokaliseerd.

Eén resourcereeks gebruiken voor meerdere klassen

De volgende code laat zien hoe u één resourcereeks gebruikt voor validatiekenmerken met meerdere klassen:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddDataAnnotationsLocalization(options => {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });
}

In de voorgaande code SharedResource is de klasse die overeenkomt met de resx waar uw validatieberichten worden opgeslagen. Met deze benadering maakt DataAnnotations alleen gebruik van SharedResource in plaats van de resource voor elke klasse.

Gelokaliseerde resources bieden voor de talen en culturen die u ondersteunt

OndersteundeCulturen en OndersteundeUICulturen

ASP.NET Core kunt u twee cultuurwaarden opgeven, SupportedCultures en SupportedUICultures. Het CultureInfo object voor SupportedCultures bepaalt de resultaten van cultuurafhankelijke functies, zoals datum, tijd, getal en valutanotatie. SupportedCultures bepaalt ook de sorteervolgorde van tekst, hoofdletterconventies en tekenreeksvergelijkingen. Voor meer informatie over hoe de server de cultuur verkrijgt, zie CultureInfo.CurrentCulture en CultureInfo.CurrentUICulture. De SupportedUICultures bepaalt welke vertaalde tekenreeksen (uit .resx bestanden) worden opgezoekd door de ResourceManager. De ResourceManager zoekt cultuurspecifieke tekenreeksen die worden bepaald door CurrentUICulture. Elke thread in .NET heeft CurrentCulture en CurrentUICulture objecten. Het framework inspecteert deze waarden bij het weergeven van cultuurafhankelijke functies. Als de cultuur van de huidige thread is ingesteld op en-US (Engels, Verenigde Staten), wordt DateTime.Now.ToLongDateString() weergegeven als Thursday, February 18, 2016; maar als CurrentCulture is ingesteld op es-ES (Spaans, Spanje), is de uitvoer jueves, 18 de febrero de 2016.

Resourcebestanden

Een resourcebestand is een handig mechanisme voor het scheiden van lokaliseerbare tekenreeksen uit code. Vertaalde tekenreeksen voor de niet-standaardtaal worden geïsoleerd in .resx-resourcebestanden . U kunt bijvoorbeeld een Spaans resourcebestand maken met de naam Welcome.es.resx met vertaalde tekenreeksen. "es" is de taalcode voor Spaans. Ga als volgt te werk om dit resourcebestand te maken in Visual Studio:

  1. Klik in Solution Explorer met de rechtermuisknop op de map die het resourcebestand zal bevatten >Toevoegen>Nieuw Item.

    Genest contextmenu: In de Solution Explorer is een contextmenu geopend voor Resources. Er is een tweede contextmenu geopend voor Toevoegen met de opdracht New Item gemarkeerd.

  2. Voer in het vak Geïnstalleerde sjablonen zoeken 'resource' in en geef het bestand een naam.

    Dialoogvenster Nieuw item toevoegen

  3. Voer de sleutelwaarde (systeemeigen tekenreeks) in de kolom Naam en de vertaalde tekenreeks in de kolom Waarde in.

    Welcome.es.resx-bestand (het welkomstbronbestand voor Spaans) met het woord Hello in de kolom Naam en het woord Hola (Hallo in het Spaans) in de kolom Waarde

    Visual Studio toont het bestand Welcome.es.resx .

    Solution Explorer toont het resourcebestand Welkom Spaans (es)

Naamgeving van bronbestand

Resources hebben de naam van het volledige type van hun klasse, met uitzondering van de assemblynaam. Een Franse resource in een project waarvan de hoofdassembly voor de klasse LocalizationWebsite.Web.dll isLocalizationWebsite.Web.Startup, heeft bijvoorbeeld de naam Startup.fr.resx. Een resource voor de klasse LocalizationWebsite.Web.Controllers.HomeController heet Controllers.HomeController.fr.resx. Als de naamruimte van uw doelklasse niet hetzelfde is als de assemblynaam, hebt u de volledige typenaam nodig. In het voorbeeldproject wordt bijvoorbeeld een resource voor het type ExtraNamespace.ToolsExtraNamespace.Tools.fr.resx genoemd.

In het voorbeeldproject wordt de ConfigureServicesResourcesPath methode ingesteld op 'Resources', zodat het relatieve projectpad voor het Franse resourcebestand van de basiscontroller Resources/Controllers.HomeController.fr.resx is. U kunt ook mappen gebruiken om resourcebestanden te ordenen. Voor de thuiscontroller zou het pad Resources/Controllers/HomeController.fr.resx zijn. Als u de ResourcesPath optie niet gebruikt, wordt het RESX-bestand in de projectbasismap weergegeven. Het bronbestand voor HomeController zou controllers.HomeController.fr.resx worden genoemd. De keuze voor het gebruik van de punt- of padnaamconventie hangt af van hoe u uw resourcebestanden wilt ordenen.

Resourcenaam Naamgeving van punten of pad
Resources/Controllers.HomeController.fr.resx Punt
Resources/Controllers/HomeController.fr.resx Pad

Resourcebestanden @inject IViewLocalizer die in Razor weergaven worden gebruikt, volgen een vergelijkbaar patroon. Het resourcebestand voor een weergave kan een naam krijgen met puntnaamgeving of padnaamgeving. Razor weergave bronbestanden bootsen het pad van hun bijbehorende bestand na. Ervan uitgaande dat we het ResourcesPath op Resources instellen, kan het Franse resourcebestand dat aan de Views/Home/About.cshtml weergave is gekoppeld, een van de volgende zijn:

  • Resources/Views/Home/About.fr.resx

  • Resources/weergaven.Home. About.fr.resx

Als u de ResourcesPath optie niet gebruikt, bevindt het RESX-bestand voor een weergave zich in dezelfde map als de weergave.

RootNaamruimteAttribuut

Het RootNamespaceAttribute kenmerk biedt de hoofdnaamruimte van een assembly wanneer de hoofdnaamruimte van een assembly anders is dan de assemblynaam.

Waarschuwing

Dit kan gebeuren wanneer de naam van een project geen geldige .NET-id is. Bijvoorbeeld: my-project-name.csproj zal de hoofdnaamruimte my_project_name en de assemblynaam my-project-name gebruiken, wat tot deze fout leidt.

Als de hoofdnaamruimte van een assembly anders is dan de assemblynaam:

  • Lokalisatie werkt niet standaard.
  • Lokalisatie mislukt vanwege de manier waarop resources binnen de assembly worden gezocht. RootNamespace is een build-time-waarde die niet beschikbaar is voor het uitvoeren van het proces.

Als de RootNamespace waarde verschilt van de AssemblyNamewaarde, neemt u het volgende op AssemblyInfo.cs in (door parameterwaarden vervangen door de werkelijke waarden):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

De voorgaande code maakt de geslaagde resolutie van resx-bestanden mogelijk.

Gedrag voor cultuurterugval

Bij het zoeken naar een resource wordt de lokalisatie betrokken bij 'cultuurterugval'. Beginnend vanuit de aangevraagde cultuur, indien niet gevonden, valt het terug op de bovenliggende cultuur van die cultuur. Terzijde: de CultureInfo.Parent eigenschap vertegenwoordigt de bovenliggende cultuur. Dit betekent meestal (maar niet altijd) dat het nationale kenmerk van de ISO wordt verwijderd. Het dialect van spaans gesproken in Mexico is bijvoorbeeld 'es-MX'. Het heeft de bovenliggende "es": Spaans, niet specifiek voor een bepaald land.

Stel dat uw site een aanvraag ontvangt voor een 'Welkom'-resource met de cultuur 'fr-CA'. Het lokalisatiesysteem zoekt naar de volgende bronnen, in volgorde, en selecteert de eerste overeenkomst.

  • Welkom.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx (als de NeutralResourcesLanguage "fr-CA" is)

Als u bijvoorbeeld de '.fr'-cultuurbenaming verwijdert en u de cultuur hebt ingesteld op Frans, wordt het standaard resourcebestand gelezen en worden tekenreeksen gelokaliseerd. De Resource Manager wijst een standaard- of terugvalresource aan voor wanneer niets voldoet aan uw aangevraagde cultuur. Als u alleen de sleutel wilt retourneren wanneer er een resource ontbreekt voor de aangevraagde cultuur, mag u geen standaardresourcebestand hebben.

Resourcebestanden genereren met Visual Studio

Als u een resourcebestand maakt in Visual Studio zonder een culturele context in de bestandsnaam (bijvoorbeeld Welcome.resx), maakt Visual Studio een C#-klasse met eigenschappen voor elke tekstregel. Dat is meestal niet wat u wilt met ASP.NET Core. Normaal gesproken hebt u geen standaard .resx-resourcebestand (een RESX-bestand zonder de naam van de cultuur). U wordt aangeraden het RESX-bestand te maken met een cultuurnaam (bijvoorbeeld Welcome.fr.resx). Wanneer u een RESX-bestand met een cultuurnaam maakt, genereert Visual Studio het klassebestand niet.

Andere culturen toevoegen

Elke combinatie van taal en cultuur (anders dan de standaardtaal) vereist een uniek resourcebestand. U maakt resourcebestanden voor verschillende culturen en landinstellingen door nieuwe bronbestanden te maken waarin de ISO-taalcodes deel uitmaken van de bestandsnaam (bijvoorbeeld en-us, fr-caen en-gb). Deze ISO-codes worden geplaatst tussen de bestandsnaam en de extensie .resx , zoals in Welkom.es-MX.resx (Spaans/Mexico).

Een strategie implementeren om de taal/cultuur voor elke aanvraag te selecteren

Lokalisatie configureren

Lokalisatie wordt geconfigureerd in de Startup.ConfigureServices methode:

services.AddLocalization(options => options.ResourcesPath = "Resources");

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization voegt de lokalisatieservices toe aan de servicescontainer. Met de bovenstaande code wordt ook het pad naar resources ingesteld op Resources.

  • AddViewLocalization voegt ondersteuning toe voor gelokaliseerde weergavebestanden. In deze voorbeeldweergavelokalisatie wordt de lokalisatie gebaseerd op het achtervoegsel van het weergavebestand. Bijvoorbeeld 'fr' in het Index.fr.cshtml bestand.

  • AddDataAnnotationsLocalization voegt ondersteuning toe voor gelokaliseerde DataAnnotations validatieberichten via IStringLocalizer abstracties.

Lokalisatie-middleware

De huidige cultuur op een aanvraag wordt ingesteld in de lokalisatie Middleware. De lokalisatie-middleware is ingeschakeld in de Startup.Configure methode. De lokalisatie-middleware moet worden geconfigureerd voordat de middleware die de verzoekcultuur kan controleren (bijvoorbeeld app.UseMvcWithDefaultRoute()). Lokalisatie-Middleware moet worden weergegeven na Routering-Middleware als u het gebruikt RouteDataRequestCultureProvider. Zie ASP.NET Core Middleware voor meer informatie over middlewarevolgorde.

var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.

UseRequestLocalization initialiseert een RequestLocalizationOptions object. Op elke aanvraag wordt de lijst met RequestCultureProvider in de RequestLocalizationOptions lijst geïnventariseerd en de eerste provider die de aanvraagcultuur kan bepalen, wordt gebruikt. De standaardproviders zijn afkomstig uit de RequestLocalizationOptions klasse:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

De standaardlijst gaat van het meest specifiek naar het minst specifiek. Verderop in het artikel zien we hoe u de volgorde kunt wijzigen en zelfs een aangepaste cultuurprovider kunt toevoegen. Als geen van de providers de aanvraagcultuur kan bepalen, wordt deze DefaultRequestCulture gebruikt.

QueryStringRequestCultureProvider

Enkele apps gebruiken een query-string om de CultureInfo in te stellen. Voor apps die gebruikmaken van de cookie of Accept-Language headerbenadering, is het toevoegen van een querytekenreeks aan de URL handig voor foutopsporing en het testen van code. Standaard wordt de QueryStringRequestCultureProvider provider geregistreerd als de eerste lokalisatieprovider in de RequestCultureProvider lijst. U geeft de queryreeksparameters culture en ui-culture. In het volgende voorbeeld wordt de specifieke cultuur (taal en regio) ingesteld op Spaans/Mexico:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Als u slechts een van de twee (culture of ui-culture) doorgeeft, worden beide waarden door de queryreeksprovider ingesteld met behulp van de waarde die u hebt doorgegeven. Als u bijvoorbeeld alleen de cultuur instelt, worden zowel Culture als UICulture ingesteld.

http://localhost:5000/?culture=es-MX

CookieRequestCultureProvider

Productie-apps bieden vaak een mechanisme om de cultuur in te stellen met de ASP.NET Kerncultuur cookie. Gebruik de methode MakeCookieValue om een cookie te creëren.

Met CookieRequestCultureProviderDefaultCookieName wordt de standaardnaam cookie geretourneerd waarmee de voorkeurscultuurinformatie van de gebruiker wordt bijgehouden. De standaardnaam cookie is .AspNetCore.Culture.

De cookie-notatie is c=%LANGCODE%|uic=%LANGCODE%, waarbij cCulture is en uicUICulture is, bijvoorbeeld:

c=en-UK|uic=en-US

Als u slechts één van cultuurgegevens en UI-cultuur opgeeft, wordt de opgegeven cultuur gebruikt voor zowel cultuurgegevens als ui-cultuur.

De Accept-Language HTTP-header

De Accept-Language header is ingesteld in de meeste browsers en was oorspronkelijk bedoeld om de taal van de gebruiker op te geven. Deze instelling geeft aan wat de browser is ingesteld om te verzenden of overgenomen van het onderliggende besturingssysteem. De Accept-Language HTTP-header van een browseraanvraag is geen onfeilbare manier om de voorkeurstaal van de gebruiker te detecteren (zie Taalvoorkeuren instellen in een browser). Een productie-app moet een manier bevatten waarop een gebruiker de keuze van cultuur kan aanpassen.

Stel de Accept-Language HTTP-header in voor IE

  1. Tik in het tandwielpictogram op Internetopties.

  2. Tik op Talen.

    Internetopties

  3. Tik op Taalvoorkeuren instellen.

  4. Tik op Een taal toevoegen.

  5. Voeg de taal toe.

  6. Tik op de taal en tik vervolgens op Omhoog verplaatsen.

Een aangepaste provider gebruiken

Stel dat u uw klanten hun taal en cultuur in uw databases wilt laten opslaan. U kunt een provider schrijven om deze waarden voor de gebruiker op te zoeken. De volgende code laat zien hoe u een aangepaste provider toevoegt:

private const string enUSCulture = "en-US";

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo(enUSCulture),
        new CultureInfo("fr")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return await Task.FromResult(new ProviderCultureResult("en"));
    }));
});

Hiermee RequestLocalizationOptions kunt u lokalisatieproviders toevoegen of verwijderen.

Volgorde van cultuurproviders voor aanvragen wijzigen

RequestLocalizationOptions heeft drie standaard aanvraag cultuurproviders: QueryStringRequestCultureProvider, CookieRequestCultureProvider en AcceptLanguageHeaderRequestCultureProvider. Gebruik de eigenschap [RequestLocalizationOptions.RequestCultureProviders]](xref:Microsoft.AspNetCore.Builder.RequestLocalizationOptions.RequestCultureProviders) om de volgorde van deze providers te wijzigen, zoals hieronder wordt weergegeven:

    app.UseRequestLocalization(options =>
    {
        var questStringCultureProvider = options.RequestCultureProviders[0];    
        options.RequestCultureProviders.RemoveAt(0);
        options.RequestCultureProviders.Insert(1, questStringCultureProvider);
    });

In het voorgaande voorbeeld wordt de volgorde van QueryStringRequestCultureProvider en CookieRequestCultureProvider omgewisseld, zodat RequestLocalizationMiddleware eerst de culturen uit de cookies zoekt en daarna de querystring.

Zoals eerder vermeld, voegt u een aangepaste provider toe via AddInitialRequestCultureProvider, die de volgorde instelt op 0, zodat deze provider prioriteit krijgt boven de andere providers.

De cultuur programmatisch instellen

Dit voorbeeldproject Localization.StarterWeb op GitHub bevat de gebruikersinterface om het Culturein te stellen. Met Views/Shared/_SelectLanguagePartial.cshtml het bestand kunt u de cultuur selecteren in de lijst met ondersteunde culturen:

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home" 
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" 
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
          onchange="this.form.submit();"
          asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
        </select>
    </form>
</div>

Het Views/Shared/_SelectLanguagePartial.cshtml bestand wordt toegevoegd aan de footer sectie van het indelingsbestand, zodat het beschikbaar is voor alle weergaven:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

Met SetLanguage de methode wordt de cultuur cookieingesteld.

[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
    Response.Cookies.Append(
        CookieRequestCultureProvider.DefaultCookieName,
        CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
        new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
    );

    return LocalRedirect(returnUrl);
}

U kunt de _SelectLanguagePartial.cshtml niet aansluiten op de voorbeeldcode voor dit project. Het project Localization.StarterWeb op GitHub bevat code om de RequestLocalizationOptions door te geven aan een Razor partial view via de Afhankelijkheidsinjectie container.

Modelbinding van routegegevens en queryreeksen

Zie het gedrag van globalisatie van modelbindingsroutegegevens en queryreeksen.

Termen voor globalisatie en lokalisatie

Het proces voor het lokaliseren van uw app vereist ook een basiskennis van relevante tekensets die vaak worden gebruikt in moderne softwareontwikkeling en inzicht in de problemen die eraan zijn gekoppeld. Hoewel alle computers tekst opslaan als getallen (codes), slaan verschillende systemen dezelfde tekst op met verschillende getallen. Het lokalisatieproces verwijst naar het vertalen van de gebruikersinterface van de app voor een specifieke cultuur/landinstelling.

Lokalisatie is een tussenliggend proces voor het controleren of een geglobaliseerde app gereed is voor lokalisatie.

De RFC 4646-indeling voor de cultuurnaam is <languagecode2>-<country/regioncode2>, waar <languagecode2> de taalcode en <country/regioncode2> de subcultuurcode is. Bijvoorbeeld voor es-CL Spaans (Chili), voor Engels (Verenigde Staten) en-US en en-AU voor Engels (Australië). RFC 4646 is een combinatie van een ISO 639-cultuurcode met twee letters die is gekoppeld aan een taal en een ISO 3166-subcultuurcode met twee letters die zijn gekoppeld aan een land of regio. Zie System.Globalization.CultureInfo voor meer informatie.

Internationalisatie wordt vaak afgekort tot "I18N". De afkorting neemt de eerste en laatste letters en het aantal letters ertussen, dus 18 staat voor het aantal letters tussen de eerste "I" en de laatste "N". Hetzelfde geldt voor Globalization (G11N) en Lokalisatie (L10N).

Voorwaarde:

  • Globalisatie (G11N): het proces voor het maken van een app ondersteunt verschillende talen en regio's.
  • Lokalisatie (L10N): Het proces voor het aanpassen van een app voor een bepaalde taal en regio.
  • Internationalisatie (I18N): beschrijft zowel globalisering als lokalisatie.
  • Cultuur: Het is een taal en, optioneel, een regio.
  • Neutrale cultuur: een cultuur met een opgegeven taal, maar geen regio. (bijvoorbeeld "en", "es")
  • Specifieke cultuur: een cultuur met een opgegeven taal en regio. (bijvoorbeeld "en-US", "en-GB", "es-CL")
  • Oorsprongscultuur: De neutrale cultuur die een specifieke cultuur omvat. (bijvoorbeeld "en" is de hoofd cultuur van "en-US" en "en-GB")
  • Taalinstelling: Een taalinstelling is hetzelfde als een taalomgeving.

Opmerking

Mogelijk kunt u geen decimale komma's invoeren in decimale velden. Als u ondersteuning wilt bieden voor jQuery-validatie voor niet-Engelstalige landinstellingen die een komma (",") gebruiken voor een decimaalteken en niet-US-English datumnotaties, moet u stappen uitvoeren om uw app te globaliseren. Zie deze GitHub-opmerking 4076 voor instructies over het toevoegen van komma's.

Opmerking

Voordat ASP.NET Core 3.0-web-apps één logboek van het type LogLevel.Warning per aanvraag schrijven als de aangevraagde cultuur niet wordt ondersteund. Het loggen van één LogLevel.Warning per verzoek kan leiden tot grote logboekbestanden met redundante informatie. Dit gedrag is gewijzigd in ASP.NET 3.0. Hiermee RequestLocalizationMiddleware wordt een logboek van het type LogLevel.Debuggeschreven, waardoor de grootte van productielogboeken wordt verkleind.

Aanvullende bronnen