Dela via


Gör innehållet i en ASP.NET Core-app localizable

Anmärkning

Det här är inte den senaste versionen av den här artikeln. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Viktigt!

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Av Hisham Bin Ateya, Damien Bowden, Bart Calixto och Nadeem Afana

En uppgift för att lokalisera en app är att omsluta lokalt innehåll med kod som gör det lättare att ersätta innehållet för olika kulturer.

IStringLocalizer

IStringLocalizer och IStringLocalizer<T> har utvecklats för att förbättra produktiviteten när lokaliserade appar utvecklas. IStringLocalizer använder både ResourceManager och ResourceReader för att tillhandahålla kulturspecifika resurser vid körning. Gränssnittet har en indexerare och en IEnumerable för att returnera lokaliserade strängar. IStringLocalizer kräver inte lagring av standardspråksträngarna i en resursfil. Du kan utveckla en app som är avsedd för lokalisering och inte behöver skapa resursfiler tidigt under utvecklingen.

I följande kodexempel visas hur du omsluter strängen "Om rubrik" för lokalisering.

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

I föregående kod kommer implementeringen IStringLocalizer<T> från Beroendeinmatning. Om det lokaliserade värdet "Om rubrik" inte hittas, returneras indexerarens nyckel, det vill säga strängen "Om rubrik".

Du kan lämna standardsträngarna för språket i appen och omsluta dem i lokalisatorn, så att du kan fokusera på att utveckla appen. Du utvecklar en app med ditt standardspråk och förbereder den för lokaliseringssteget utan att först skapa en standardresursfil.

Du kan också använda den traditionella metoden och ange en nyckel för att hämta standardspråksträngen. För många utvecklare kan det nya arbetsflödet med att inte ha en .resx-standardfil och bara omsluta strängliteralerna minska kostnaderna för att lokalisera en app. Andra utvecklare föredrar det traditionella arbetsflödet eftersom det kan vara enklare att arbeta med långa strängliteraler och enklare att uppdatera lokaliserade strängar.

IHtmlLocalizer

Använd implementeringen IHtmlLocalizer<TResource> för resurser som innehåller HTML. IHtmlLocalizer HTML-kodar argument som är formaterade i resurssträngen, men som inte HTML-kodar själva resurssträngen. I följande markerade kod är endast värdet för parametern name HTML-kodat.

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

NOT: I allmänhet är det bara att lokalisera text, inte HTML.

IStringLocalizerFactory

På den lägsta nivån IStringLocalizerFactory kan hämtas från beroendeinsprutning:

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

Föregående kod visar var och en av de två metoderna för att skapa fabrik.

Delade resurser

Du kan partitionera dina lokaliserade strängar efter styrenhet eller område eller bara ha en container. I exempelappen används en markörklass med namnet SharedResource för delade resurser. Markörklassen anropas aldrig:

// Dummy class to group shared resources

namespace Localization;

public class SharedResource
{
}

I följande exempel används lokaliserarna InfoController och 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;
    }

Visa lokalisering

Tjänsten IViewLocalizer tillhandahåller lokaliserade strängar för en vy. Klassen ViewLocalizer implementerar det här gränssnittet och hittar resursens plats utifrån sökvägen för vyfilen. Följande kod visar hur du använder standardimplementeringen av 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>

Standardimplementeringen av IViewLocalizer hittar resursfilen baserat på vyns filnamn. Det finns inget alternativ för att använda en global delad resursfil. ViewLocalizer implementerar lokaliseringen med IHtmlLocalizer, så Razor HTML-kodar inte den lokaliserade strängen. Du kan parametrisera resurssträngar och IViewLocalizer HTML-kodar parametrarna men inte resurssträngen. Överväg följande Razor markup:

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

En fransk resursfil kan innehålla följande värden:

Nyckel Värde
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Den renderade vyn skulle innehålla HTML-markering från resursfilen.

I allmänhet lokalisera endast text, inte HTML.

Om du vill använda en delad resursfil i en vy matar du in 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>

Lokalisering av DataAnnotations

Felmeddelanden för DataAnnotations lokaliseras med IStringLocalizer<T>. Med alternativet ResourcesPath = "Resources"kan felmeddelandena i RegisterViewModel lagras i någon av följande sökvägar:

  • Resurser/ViewModels.Account.RegisterViewModel.fr.resx
  • Resurser/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; }
}

Attribut som inte är för validering är lokaliserade.

Använda en resurssträng för flera klasser

Följande kod visar hur du använder en resurssträng för valideringsattribut med flera klasser:

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

I föregående kod SharedResource är klassen som motsvarar .resx-filen där valideringsmeddelandena lagras. Med detta tillvägagångssätt använder DataAnnotations endast SharedResource, istället för resursen för varje klass.

Konfigurera lokaliseringstjänster

Lokaliseringstjänster konfigureras i Program.cs:

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization lägger till lokaliseringstjänster i tjänstcontainern, inklusive implementeringar för IStringLocalizer<T> och IStringLocalizerFactory. Föregående kod anger även resurssökvägen till "Resurser".

  • AddViewLocalization lägger till stöd för lokaliserade vyfiler. I det här exemplet baseras lokaliseringen på vyfilsuffixet. Till exempel "fr" i Index.fr.cshtml filen.

  • AddDataAnnotationsLocalization lägger till stöd för lokaliserade valideringsmeddelanden DataAnnotations via IStringLocalizer abstraktioner.

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Nästa steg

När du lokaliserar en app ingår även följande uppgifter:

Ytterligare resurser

Av Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana och Hisham Bin Ateya

En uppgift för att lokalisera en app är att omsluta lokalt innehåll med kod som gör det lättare att ersätta innehållet för olika kulturer.

IStringLocalizer

IStringLocalizer och IStringLocalizer<T> har utvecklats för att förbättra produktiviteten när lokaliserade appar utvecklas. IStringLocalizer använder både ResourceManager och ResourceReader för att tillhandahålla kulturspecifika resurser vid körning. Gränssnittet har en indexerare och en IEnumerable för att returnera lokaliserade strängar. IStringLocalizer kräver inte lagring av standardspråksträngarna i en resursfil. Du kan utveckla en app som är avsedd för lokalisering och inte behöver skapa resursfiler tidigt under utvecklingen.

I följande kodexempel visas hur du omsluter strängen "Om rubrik" för lokalisering.

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

I föregående kod kommer implementeringen IStringLocalizer<T> från Beroendeinmatning. Om det lokaliserade värdet "Om rubrik" inte hittas, returneras indexerarens nyckel, det vill säga strängen "Om rubrik".

Du kan lämna standardsträngarna för språket i appen och omsluta dem i lokalisatorn, så att du kan fokusera på att utveckla appen. Du utvecklar en app med ditt standardspråk och förbereder den för lokaliseringssteget utan att först skapa en standardresursfil.

Du kan också använda den traditionella metoden och ange en nyckel för att hämta standardspråksträngen. För många utvecklare kan det nya arbetsflödet med att inte ha en .resx-standardfil och bara omsluta strängliteralerna minska kostnaderna för att lokalisera en app. Andra utvecklare föredrar det traditionella arbetsflödet eftersom det kan vara enklare att arbeta med långa strängliteraler och enklare att uppdatera lokaliserade strängar.

IHtmlLocalizer

Använd implementeringen IHtmlLocalizer<T> för resurser som innehåller HTML. IHtmlLocalizer HTML-kodar argument som är formaterade i resurssträngen, men som inte HTML-kodar själva resurssträngen. I följande markerade kod är endast värdet för parametern name HTML-kodat.

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

Anmärkning

I allmänhet bör man endast lokalisera texten, inte HTML.

IStringLocalizerFactory

På lägsta nivån kan du få IStringLocalizerFactory ur beroendeinjektionen:

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

Föregående kod visar var och en av de två metoderna för att skapa fabrik.

Delade resurser

Du kan partitionera dina lokaliserade strängar efter styrenhet eller område eller bara ha en container. I exempelappen används en dummyklass med namnet SharedResource för delade resurser.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Vissa utvecklare använder Startup klassen för att innehålla globala eller delade strängar. I följande exempel används lokaliserarna InfoController och 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;
    }

Visa lokalisering

Tjänsten IViewLocalizer tillhandahåller lokaliserade strängar för en vy. Klassen ViewLocalizer implementerar det här gränssnittet och hittar resursens plats utifrån sökvägen för vyfilen. Följande kod visar hur du använder standardimplementeringen av 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>

Standardimplementeringen av IViewLocalizer hittar resursfilen baserat på vyns filnamn. Det finns inget alternativ för att använda en global delad resursfil. ViewLocalizer implementerar lokaliseringen med IHtmlLocalizer, så Razor HTML-kodar inte den lokaliserade strängen. Du kan parametrisera resurssträngar och IViewLocalizer HTML-kodar parametrarna men inte resurssträngen. Överväg följande Razor markup:

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

En fransk resursfil kan innehålla följande värden:

Nyckel Värde
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Den renderade vyn skulle innehålla HTML-markering från resursfilen.

Anmärkning

I allmänhet bör man endast lokalisera texten, inte HTML.

Om du vill använda en delad resursfil i en vy matar du in 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>

Lokalisering av DataAnnotations

Felmeddelanden för DataAnnotations lokaliseras med IStringLocalizer<T>. Med alternativet ResourcesPath = "Resources"kan felmeddelandena i RegisterViewModel lagras i någon av följande sökvägar:

  • Resurser/ViewModels.Account.RegisterViewModel.fr.resx
  • Resurser/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; }
}

I ASP.NET Core MVC 1.1.0 eller senare blir icke-valideringsattributen lokaliserade.

Använda en resurssträng för flera klasser

Följande kod visar hur du använder en resurssträng för valideringsattribut med flera klasser:

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

I föregående kod SharedResource är klassen som motsvarar .resx-filen där valideringsmeddelandena lagras. Med detta tillvägagångssätt använder DataAnnotations endast SharedResource, istället för resursen för varje klass.

Konfigurera lokaliseringstjänster

Lokaliseringstjänster konfigureras i Startup.ConfigureServices metoden:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization lägger till lokaliseringstjänster i tjänstcontainern, inklusive implementeringar för IStringLocalizer<T> och IStringLocalizerFactory. Föregående kod anger även resurssökvägen till "Resurser".

  • AddViewLocalization lägger till stöd för lokaliserade vyfiler. I det här exemplet baseras lokaliseringen på vyfilsuffixet. Till exempel "fr" i Index.fr.cshtml filen.

  • AddDataAnnotationsLocalization lägger till stöd för lokaliserade valideringsmeddelanden DataAnnotations via IStringLocalizer abstraktioner.

Anmärkning

Du kanske inte kan ange decimaltecken i decimalfält. Om du vill stödja jQuery-validering för språkvarianter som inte är engelska och som använder kommatecken (",") för decimaltecken och datumformat som inte US-English måste du vidta åtgärder för att globalisera din app. Se den här GitHub-kommentaren 4076 för instruktioner om hur du lägger till decimal kommatecken.

Nästa steg

När du lokaliserar en app ingår även följande uppgifter:

Ytterligare resurser