Rendre localisable le contenu d’une application ASP.NET Core
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 8 de cet article.
Par Hisham Bin Ateya, Damien Bowden, Bart Calixto et Nadeem Afana
L’une des tâches de la localisation d’une application consiste à envelopper le contenu localisable avec un code qui facilite le remplacement de ce contenu pour différentes cultures.
IStringLocalizer
IStringLocalizer et IStringLocalizer<T> ont été conçus pour améliorer la productivité lors du développement d’applications localisées. IStringLocalizer
utilise ResourceManager et ResourceReader pour fournir des ressources spécifiques à la culture au moment de l’exécution. L’interface possède un indexeur et un IEnumerable
pour retourner des chaînes localisées. IStringLocalizer
n’exige pas de stocker les chaînes de langue par défaut dans un fichier de ressources. Vous pouvez développer une application ciblée pour la localisation sans avoir besoin de créer des fichiers de ressources au tout début du développement.
Le code ci-dessous montre comment envelopper la chaîne « About Title » à des fins de localisation.
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"];
}
}
Dans le code précédent, l’implémentation de IStringLocalizer<T>
vient de l’injection de dépendances. Si la valeur localisée de « About Title » est introuvable, alors la clé de l’indexeur est retournée, autrement dit, la chaîne « About Title ».
Vous pouvez laisser les chaînes littérales de la langue par défaut dans l’application et les inclure dans un wrapper dans le localisateur, afin de pouvoir vous concentrer sur le développement de l’application. Vous développez une application avec votre langue par défaut et vous la préparez à l’étape de localisation sans créer au préalable un fichier de ressources par défaut.
Vous pouvez également utiliser l’approche traditionnelle et fournir une clé pour récupérer la chaîne de la langue par défaut. Pour de nombreux développeurs, le nouveau workflow qui n’inclut pas de fichier .resx de langue par défaut et qui consiste à simplement inclure dans un wrapper les littéraux de chaîne permet de réduire la surcharge de la localisation d’une application. D’autres développeurs préfèrent le workflow traditionnel, car il facilite l’utilisation de longs littéraux de chaîne ainsi que la mise à jour des chaînes localisées.
IHtmlLocalizer
Utilisez l’implémentation de IHtmlLocalizer<TResource> pour les ressources qui contiennent du HTML. IHtmlLocalizer encode en HTML les arguments formatés dans la chaîne de ressource, mais pas la chaîne de ressource elle-même. Dans le code mis en surbrillance suivant, seule la valeur du paramètre name
est encodée au format 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();
}
Remarque : En règle générale, localisez uniquement le texte et non le code HTML.
IStringLocalizerFactory
Au niveau le plus bas, IStringLocalizerFactory peut être récupéré à partir de l’Injection de dépendances :
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();
}
Le code ci-dessus illustre chacune des deux méthodes de création.
Ressources partagées
Vous pouvez partitionner vos chaînes localisées par contrôleur, par zone, ou avoir un seul conteneur. Dans l’exemple d’application, un marqueur avec nom de la classe SharedResource
est utilisée pour les ressources partagées. La classe du marqueur n’est jamais appelée :
// Dummy class to group shared resources
namespace Localization;
public class SharedResource
{
}
Dans l’exemple ci-dessous, les localiseurs InfoController
et SharedResource
sont utilisés :
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;
}
Localisation de l’affichage
Le service IViewLocalizer fournit des chaînes localisées à une vue. La classe ViewLocalizer
implémente cette interface et recherche l’emplacement de la ressource à partir du chemin du fichier de la vue. Le code suivant montre comment utiliser l’implémentation par défaut de 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>
L’implémentation par défaut de IViewLocalizer
recherche le fichier de ressources en fonction du nom de fichier de l’affichage. Il n’existe aucune option pour utiliser un fichier de ressources partagées globales. ViewLocalizer
implémente le localiseur en utilisant IHtmlLocalizer
, si bien que Razor n’encode pas en HTML la chaîne localisée. Vous pouvez paramétrer des chaînes de ressources, et IViewLocalizer
encode en HTML les paramètres, mais pas les chaînes de ressources. Examinons le balisage Razor suivant :
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Un fichier de ressources en français peut contenir les valeurs suivantes :
Clé | Valeur |
---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
L’affichage contient le balisage HTML provenant du fichier de ressources.
En règle générale, localisez uniquement le texte et non le code HTML.
Pour utiliser un fichier de ressources partagées dans un affichage, injectez 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>
Localisation de DataAnnotations
Les messages d’erreur DataAnnotations sont localisés avec IStringLocalizer<T>
. En utilisant l’option ResourcesPath = "Resources"
, les messages d’erreur inclus dans RegisterViewModel
peuvent être stockés dans les chemins suivants :
- 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; }
}
Les attributs hors validation sont localisés.
Comment utiliser une seule chaîne de ressource pour plusieurs classes
Le code suivant montre comment utiliser une seule chaîne de ressource pour les attributs de validation avec plusieurs classes :
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
Dans le code précédent, SharedResource
est la classe correspondant au fichier .resx où sont stockés les messages de validation. Cette approche permet à DataAnnotations d’utiliser uniquement SharedResource
, au lieu de la ressource de chaque classe.
Configurer les services de localisation
Les services de localisation sont configurés dans Program.cs
:
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization ajoute les services de localisation au conteneur de services, y compris les implémentations pour
IStringLocalizer<T>
etIStringLocalizerFactory
. Le code ci-dessus affecte également la valeur « Resources » au chemin des ressources.AddViewLocalization ajoute la prise en charge des fichiers de vues localisées. Dans cet exemple de vue, la localisation se base sur le suffixe du fichier de la vue. Par exemple, « fr » dans le fichier
Index.fr.cshtml
.AddDataAnnotationsLocalization ajoute la prise en charge des messages de validation
DataAnnotations
localisés par le biais d’abstractionsIStringLocalizer
.
Remarque
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Étapes suivantes
La localisation d’une application implique également les tâches suivantes :
- Fournir des ressources localisées aux langues et cultures prises en charge par l’application
- Implémenter une stratégie de sélection de la langue/culture pour chaque requête
Ressources supplémentaires
- Fournisseur de culture d’URL qui utilise des intergiciels comme filtres dans ASP.NET Core
- Application globale de RouteDataRequest CultureProvider avec des intergiciel en tant que filtres
- Globalisation et localisation dans ASP.NET Core
- Fournir des ressources localisées pour les langues et les cultures dans une application ASP.NET Core
- Stratégies de sélection de la langue et de la culture dans une application ASP.NET Core localisée
- Résoudre les problèmes liés à la localisation ASP.NET Core
- Internationalisation et localisation d’applications .NET
- Projet Localization.StarterWeb utilisé dans l’article.
- Ressources dans les fichiers .resx
- Kit de ressources pour application multilingue Microsoft
- Localisation et classes génériques
Par Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana et Hisham Bin Ateya
L’une des tâches de la localisation d’une application consiste à envelopper le contenu localisable avec un code qui facilite le remplacement de ce contenu pour différentes cultures.
IStringLocalizer
IStringLocalizer et IStringLocalizer<T> ont été conçus pour améliorer la productivité lors du développement d’applications localisées. IStringLocalizer
utilise ResourceManager et ResourceReader pour fournir des ressources spécifiques à la culture au moment de l’exécution. L’interface possède un indexeur et un IEnumerable
pour retourner des chaînes localisées. IStringLocalizer
n’exige pas de stocker les chaînes de langue par défaut dans un fichier de ressources. Vous pouvez développer une application ciblée pour la localisation sans avoir besoin de créer des fichiers de ressources au tout début du développement.
Le code ci-dessous montre comment envelopper la chaîne « About Title » à des fins de localisation.
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"];
}
}
}
Dans le code précédent, l’implémentation de IStringLocalizer<T>
vient de l’injection de dépendances. Si la valeur localisée de « About Title » est introuvable, alors la clé de l’indexeur est retournée, autrement dit, la chaîne « About Title ».
Vous pouvez laisser les chaînes littérales de la langue par défaut dans l’application et les inclure dans un wrapper dans le localisateur, afin de pouvoir vous concentrer sur le développement de l’application. Vous développez une application avec votre langue par défaut et vous la préparez à l’étape de localisation sans créer au préalable un fichier de ressources par défaut.
Vous pouvez également utiliser l’approche traditionnelle et fournir une clé pour récupérer la chaîne de la langue par défaut. Pour de nombreux développeurs, le nouveau workflow qui n’inclut pas de fichier .resx de langue par défaut et qui consiste à simplement inclure dans un wrapper les littéraux de chaîne permet de réduire la surcharge de la localisation d’une application. D’autres développeurs préfèrent le workflow traditionnel, car il facilite l’utilisation de longs littéraux de chaîne ainsi que la mise à jour des chaînes localisées.
IHtmlLocalizer
Utilisez l’implémentation de IHtmlLocalizer<T>
pour les ressources qui contiennent du HTML. IHtmlLocalizer
encode en HTML les arguments formatés dans la chaîne de ressource, mais pas la chaîne de ressource elle-même. Dans le code mis en surbrillance suivant, seule la valeur du paramètre name
est encodée au format 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();
}
Remarque
En règle générale, localisez uniquement le texte et non le code HTML.
IStringLocalizerFactory
Au niveau le plus bas, vous pouvez sortir IStringLocalizerFactory
de l’injection de dépendances :
{
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."];
Le code ci-dessus illustre chacune des deux méthodes de création.
Ressources partagées
Vous pouvez partitionner vos chaînes localisées par contrôleur, par zone, ou avoir un seul conteneur. Dans l’exemple d’application, une classe fictive nommée SharedResource
est utilisée pour les ressources partagées.
// Dummy class to group shared resources
namespace Localization
{
public class SharedResource
{
}
}
Certains développeurs utilisent la classe Startup
pour contenir des chaînes globales ou partagées. Dans l’exemple ci-dessous, les localiseurs InfoController
et SharedResource
sont utilisés :
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;
}
Localisation de l’affichage
Le service IViewLocalizer
fournit des chaînes localisées à une vue. La classe ViewLocalizer
implémente cette interface et recherche l’emplacement de la ressource à partir du chemin du fichier de la vue. Le code suivant montre comment utiliser l’implémentation par défaut de 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>
L’implémentation par défaut de IViewLocalizer
recherche le fichier de ressources en fonction du nom de fichier de l’affichage. Il n’existe aucune option pour utiliser un fichier de ressources partagées globales. ViewLocalizer
implémente le localiseur en utilisant IHtmlLocalizer
, si bien que Razor n’encode pas en HTML la chaîne localisée. Vous pouvez paramétrer des chaînes de ressources, et IViewLocalizer
encode en HTML les paramètres, mais pas les chaînes de ressources. Examinons le balisage Razor suivant :
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Un fichier de ressources en français peut contenir les valeurs suivantes :
Clé | Valeur |
---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
L’affichage contient le balisage HTML provenant du fichier de ressources.
Remarque
En règle générale, localisez uniquement le texte et non le code HTML.
Pour utiliser un fichier de ressources partagées dans un affichage, injectez 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>
Localisation de DataAnnotations
Les messages d’erreur DataAnnotations sont localisés avec IStringLocalizer<T>
. En utilisant l’option ResourcesPath = "Resources"
, les messages d’erreur inclus dans RegisterViewModel
peuvent être stockés dans les chemins suivants :
- 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; }
}
Dans ASP.NET Core MVC 1.1.0 et version ultérieure, les attributs de non-validation sont localisés.
Comment utiliser une seule chaîne de ressource pour plusieurs classes
Le code suivant montre comment utiliser une seule chaîne de ressource pour les attributs de validation avec plusieurs classes :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
Dans le code précédent, SharedResource
est la classe correspondant au fichier .resx où sont stockés les messages de validation. Cette approche permet à DataAnnotations d’utiliser uniquement SharedResource
, au lieu de la ressource de chaque classe.
Configurer les services de localisation
Les services de localisation sont configurés dans la méthode Startup.ConfigureServices
:
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
AddLocalization
ajoute les services de localisation au conteneur de services, y compris les implémentations pourIStringLocalizer<T>
etIStringLocalizerFactory
. Le code ci-dessus affecte également la valeur « Resources » au chemin des ressources.AddViewLocalization
ajoute la prise en charge des fichiers de vues localisées. Dans cet exemple de vue, la localisation se base sur le suffixe du fichier de la vue. Par exemple, « fr » dans le fichierIndex.fr.cshtml
.AddDataAnnotationsLocalization
ajoute la prise en charge des messages de validationDataAnnotations
localisés par le biais d’abstractionsIStringLocalizer
.
Remarque
Vous ne pourrez peut-être pas entrer de virgules décimales dans les champs décimaux. Pour prendre en charge la validation jQuery pour les paramètres régionaux autres que l’anglais qui utilisent une virgule (« , ») comme décimale et des formats de date autres que l’anglais des États-Unis, vous devez effectuer des étapes pour localiser votre application. Consultez ce commentaire GitHub 4076 pour savoir comment ajouter une virgule décimale.
Étapes suivantes
La localisation d’une application implique également les tâches suivantes :
- Fournir des ressources localisées aux langues et cultures prises en charge par l’application
- Implémenter une stratégie de sélection de la langue/culture pour chaque requête
Ressources supplémentaires
- Globalisation et localisation dans ASP.NET Core
- Fournir des ressources localisées pour les langues et les cultures dans une application ASP.NET Core
- Stratégies de sélection de la langue et de la culture dans une application ASP.NET Core localisée
- Résoudre les problèmes liés à la localisation ASP.NET Core
- Internationalisation et localisation d’applications .NET
- Projet Localization.StarterWeb utilisé dans l’article.
- Ressources dans les fichiers .resx
- Kit de ressources pour application multilingue Microsoft
- Localisation et classes génériques