Aracılığıyla paylaş


ASP.NET Core uygulamasının içeriğini yerelleştirilebilir hale getirme

Hisham Bin Ateya, Damien Bowden, Bart Calixto ve Nadeem Afana tarafından

Bir uygulamayı yerelleştirmeye yönelik bir görev, yerelleştirilebilir içeriği farklı kültürler için bu içeriğin değiştirilmesini kolaylaştıran bir kodla kaydırmaktır.

IStringLocalizer

IStringLocalizer ve IStringLocalizer<T> yerelleştirilmiş uygulamalar geliştirirken üretkenliği artırmak için tasarlanmıştır. IStringLocalizerResourceManager çalışma zamanında kültüre özgü kaynaklar sağlamak için ve ResourceReader kullanır. Arabirimin bir dizin oluşturucu ve yerelleştirilmiş dizeleri döndürmek için bir IEnumerable değeri vardır. IStringLocalizer varsayılan dil dizelerinin bir kaynak dosyasında depolanmasını gerektirmez. Yerelleştirme için hedeflenen bir uygulama geliştirebilirsiniz ve geliştirmenin erken aşamalarında kaynak dosyaları oluşturmanız gerekmez.

Aşağıdaki kod örneğinde, yerelleştirme için "Başlık Hakkında" dizesinin nasıl kaydırılır gösterilmektedir.

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

Yukarıdaki koddaIStringLocalizer<T>, uygulama Bağımlılık Ekleme'den gelir. "Başlık Hakkında" yerelleştirilmiş değeri bulunamazsa, dizin oluşturucu anahtarı döndürülür, yani "Başlık Hakkında" dizesi.

Varsayılan dil değişmez dizelerini uygulamada bırakabilir ve uygulamayı geliştirmeye odaklanabilmeniz için yerelleştiriciye sarmalayabilirsiniz. Varsayılan dilinizle bir uygulama geliştirir ve önce varsayılan bir kaynak dosyası oluşturmadan yerelleştirme adımına hazırlarsınız.

Alternatif olarak, geleneksel yaklaşımı kullanabilir ve varsayılan dil dizesini almak için bir anahtar sağlayabilirsiniz. Birçok geliştirici için, varsayılan dil .resx dosyasına sahip olmayan ve yalnızca dize değişmez değerlerini sarmalayan yeni iş akışı, bir uygulamayı yerelleştirme yükünü azaltabilir. Diğer geliştiriciler, uzun dize değişmez değerleriyle çalışmak ve yerelleştirilmiş dizeleri güncelleştirmek daha kolay olabileceğinden geleneksel iş akışını tercih eder.

IHtmlLocalizer

IHtmlLocalizer<TResource> UYGULAMAYı HTML içeren kaynaklar için kullanın. IHtmlLocalizer HTML, kaynak dizesinde biçimlendirilmiş bağımsız değişkenleri kodlar, ancak kaynak dizesini HTML ile kodlamaz. Aşağıdaki vurgulanmış kodda, yalnızca parametresinin name değeri HTML ile kodlanmıştır.

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: Genel olarak, HTML'yi değil yalnızca metni yerelleştirin.

IStringLocalizerFactory

En düşük düzeyde, IStringLocalizerFactory Bağımlılık Ekleme'den alınabilir:

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

Yukarıdaki kod, iki fabrika oluşturma yönteminin her birini gösterir.

Paylaşılan kaynaklar

Yerelleştirilmiş dizelerinizi denetleyiciye veya alana göre bölümleyebilir veya yalnızca bir kapsayıcınız olabilir. Örnek uygulamada, paylaşılan kaynaklar için adlı SharedResource bir işaretçi sınıfı kullanılır. marker sınıfı hiçbir zaman çağrılmaz:

// Dummy class to group shared resources

namespace Localization;

public class SharedResource
{
}

Aşağıdaki örnekte InfoController ve SharedResource yerelleştiricileri kullanılır:

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

Yerelleştirmeyi görüntüle

Hizmet, IViewLocalizer bir görünüm için yerelleştirilmiş dizeler sağlar. ViewLocalizer sınıfı bu arabirimi uygular ve görünüm dosyası yolundan kaynak konumunu bulur. Aşağıdaki kod, uygulamasının varsayılan uygulamasının IViewLocalizernasıl kullanılacağını gösterir:

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

varsayılan uygulaması IViewLocalizer , görünümün dosya adına göre kaynak dosyasını bulur. Genel paylaşılan kaynak dosyası kullanma seçeneği yoktur. ViewLocalizer kullanarak IHtmlLocalizeryerelleştiriciyi uygular, bu nedenle Razor yerelleştirilmiş dizeyi HTML ile kodlamaz. Kaynak dizelerini parametreleştirebilirsiniz ve IViewLocalizer HTML ile parametreleri kodlayabilir, ancak kaynak dizesini kodlayabilirsiniz. Aşağıdaki Razor işaretlemeyi göz önünde bulundurun:

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

Fransızca kaynak dosyası aşağıdaki değerleri içerebilir:

Anahtar Değer
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

İşlenen görünüm, kaynak dosyasındaki HTML işaretlemesini içerir.

Genel olarak, HTML'yi değil, yalnızca metni yerelleştirin.

Paylaşılan kaynak dosyasını bir görünümde kullanmak için ekleyin 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>

DataAnnotations yerelleştirmesi

DataAnnotations hata iletileri ile IStringLocalizer<T>yerelleştirilir. seçeneğini ResourcesPath = "Resources"kullanarak içindeki RegisterViewModel hata iletileri aşağıdaki yollardan birinde depolanabilir:

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

Doğrulama olmayan öznitelikler yerelleştirilir.

Birden çok sınıf için bir kaynak dizesi kullanma

Aşağıdaki kod, birden çok sınıfa sahip doğrulama öznitelikleri için bir kaynak dizesinin nasıl kullanılacağını gösterir:

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

Yukarıdaki kodda, SharedResource doğrulama iletilerinin depolandığı .resx dosyasına karşılık gelen sınıftır. Bu yaklaşımla, DataAnnotations her sınıfın kaynağı yerine yalnızca kullanır SharedResource.

Yerelleştirme hizmetlerini yapılandırma

Yerelleştirme hizmetleri içinde Program.csyapılandırılır:

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

builder.Services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalizationve IStringLocalizerFactoryuygulamaları dahil olmak üzere yerelleştirme hizmetlerini services kapsayıcısına IStringLocalizer<T> ekler. Yukarıdaki kod, kaynak yolunu da "Kaynaklar" olarak ayarlar.

  • AddViewLocalization yerelleştirilmiş görünüm dosyaları için destek ekler. Bu örnekte görünüm yerelleştirmesi, görünüm dosyası son ekini temel alır. Örneğin, dosyadaki Index.fr.cshtml "fr".

  • AddDataAnnotationsLocalizationsoyutlamalar aracılığıyla IStringLocalizer yerelleştirilmiş DataAnnotations doğrulama iletileri için destek ekler.

Not

Ondalık alanlara ondalık virgül giremeyebilirsiniz. Ondalık ayırıcı için virgül (",") ve ABD İngilizcesi olmayan tarih biçimleri kullanan İngilizce olmayan yerel ayarlar için jQuery doğrulamasını desteklemek için uygulamanızı genelleştirme adımlarını uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub açıklama 4076'ya bakın.

Sonraki adımlar

Bir uygulamayı yerelleştirmek aşağıdaki görevleri de içerir:

Ek kaynaklar

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

Bir uygulamayı yerelleştirmeye yönelik bir görev, yerelleştirilebilir içeriği farklı kültürler için bu içeriğin değiştirilmesini kolaylaştıran bir kodla kaydırmaktır.

IStringLocalizer

IStringLocalizer ve IStringLocalizer<T> yerelleştirilmiş uygulamalar geliştirirken üretkenliği artırmak için tasarlanmıştır. IStringLocalizerResourceManager çalışma zamanında kültüre özgü kaynaklar sağlamak için ve ResourceReader kullanır. Arabirimin bir dizin oluşturucu ve yerelleştirilmiş dizeleri döndürmek için bir IEnumerable değeri vardır. IStringLocalizer varsayılan dil dizelerinin bir kaynak dosyasında depolanmasını gerektirmez. Yerelleştirme için hedeflenen bir uygulama geliştirebilirsiniz ve geliştirmenin erken aşamalarında kaynak dosyaları oluşturmanız gerekmez.

Aşağıdaki kod örneğinde, yerelleştirme için "Başlık Hakkında" dizesinin nasıl kaydırılır gösterilmektedir.

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

Yukarıdaki koddaIStringLocalizer<T>, uygulama Bağımlılık Ekleme'den gelir. "Başlık Hakkında" yerelleştirilmiş değeri bulunamazsa, dizin oluşturucu anahtarı döndürülür, yani "Başlık Hakkında" dizesi.

Varsayılan dil değişmez dizelerini uygulamada bırakabilir ve uygulamayı geliştirmeye odaklanabilmeniz için yerelleştiriciye sarmalayabilirsiniz. Varsayılan dilinizle bir uygulama geliştirir ve önce varsayılan bir kaynak dosyası oluşturmadan yerelleştirme adımına hazırlarsınız.

Alternatif olarak, geleneksel yaklaşımı kullanabilir ve varsayılan dil dizesini almak için bir anahtar sağlayabilirsiniz. Birçok geliştirici için, varsayılan dil .resx dosyasına sahip olmayan ve yalnızca dize değişmez değerlerini sarmalayan yeni iş akışı, bir uygulamayı yerelleştirme yükünü azaltabilir. Diğer geliştiriciler, uzun dize değişmez değerleriyle çalışmak ve yerelleştirilmiş dizeleri güncelleştirmek daha kolay olabileceğinden geleneksel iş akışını tercih eder.

IHtmlLocalizer

IHtmlLocalizer<T> UYGULAMAYı HTML içeren kaynaklar için kullanın. IHtmlLocalizer HTML, kaynak dizesinde biçimlendirilmiş bağımsız değişkenleri kodlar, ancak kaynak dizesini HTML ile kodlamaz. Aşağıdaki vurgulanmış kodda, yalnızca parametresinin name değeri HTML ile kodlanmıştır.

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

Genel olarak, HTML'yi değil, yalnızca metni yerelleştirin.

IStringLocalizerFactory

En düşük düzeyde Bağımlılık Ekleme'yi kullanabilirsinizIStringLocalizerFactory:

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

Yukarıdaki kod, iki fabrika oluşturma yönteminin her birini gösterir.

Paylaşılan kaynaklar

Yerelleştirilmiş dizelerinizi denetleyiciye veya alana göre bölümleyebilir veya yalnızca bir kapsayıcınız olabilir. Örnek uygulamada, paylaşılan kaynaklar için adlı SharedResource bir sahte sınıf kullanılır.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Bazı geliştiriciler genel veya paylaşılan dizeler içermek için sınıfını Startup kullanır. Aşağıdaki örnekte InfoController ve SharedResource yerelleştiricileri kullanılır:

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

Yerelleştirmeyi görüntüle

Hizmet, IViewLocalizer bir görünüm için yerelleştirilmiş dizeler sağlar. ViewLocalizer sınıfı bu arabirimi uygular ve görünüm dosyası yolundan kaynak konumunu bulur. Aşağıdaki kod, uygulamasının varsayılan uygulamasının IViewLocalizernasıl kullanılacağını gösterir:

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

varsayılan uygulaması IViewLocalizer , görünümün dosya adına göre kaynak dosyasını bulur. Genel paylaşılan kaynak dosyası kullanma seçeneği yoktur. ViewLocalizer kullanarak IHtmlLocalizeryerelleştiriciyi uygular, bu nedenle Razor yerelleştirilmiş dizeyi HTML ile kodlamaz. Kaynak dizelerini parametreleştirebilirsiniz ve IViewLocalizer HTML ile parametreleri kodlayabilir, ancak kaynak dizesini kodlayabilirsiniz. Aşağıdaki Razor işaretlemeyi göz önünde bulundurun:

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

Fransızca kaynak dosyası aşağıdaki değerleri içerebilir:

Anahtar Değer
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

İşlenen görünüm, kaynak dosyasındaki HTML işaretlemesini içerir.

Not

Genel olarak, HTML'yi değil, yalnızca metni yerelleştirin.

Paylaşılan kaynak dosyasını bir görünümde kullanmak için ekleyin 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>

DataAnnotations yerelleştirmesi

DataAnnotations hata iletileri ile IStringLocalizer<T>yerelleştirilir. seçeneğini ResourcesPath = "Resources"kullanarak içindeki RegisterViewModel hata iletileri aşağıdaki yollardan birinde depolanabilir:

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

ASP.NET Core MVC 1.1.0 ve sonraki sürümlerinde doğrulama dışı öznitelikler yerelleştirilir.

Birden çok sınıf için bir kaynak dizesi kullanma

Aşağıdaki kod, birden çok sınıfa sahip doğrulama öznitelikleri için bir kaynak dizesinin nasıl kullanılacağını gösterir:

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

Yukarıdaki kodda, SharedResource doğrulama iletilerinin depolandığı .resx dosyasına karşılık gelen sınıftır. Bu yaklaşımla, DataAnnotations her sınıfın kaynağı yerine yalnızca kullanır SharedResource.

Yerelleştirme hizmetlerini yapılandırma

Yerelleştirme hizmetleri yönteminde Startup.ConfigureServices yapılandırılır:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalizationve IStringLocalizerFactoryuygulamaları dahil olmak üzere yerelleştirme hizmetlerini services kapsayıcısına IStringLocalizer<T> ekler. Yukarıdaki kod, kaynak yolunu da "Kaynaklar" olarak ayarlar.

  • AddViewLocalization yerelleştirilmiş görünüm dosyaları için destek ekler. Bu örnekte görünüm yerelleştirmesi, görünüm dosyası son ekini temel alır. Örneğin, dosyadaki Index.fr.cshtml "fr".

  • AddDataAnnotationsLocalizationsoyutlamalar aracılığıyla IStringLocalizer yerelleştirilmiş DataAnnotations doğrulama iletileri için destek ekler.

Not

Ondalık alanlara ondalık virgül giremeyebilirsiniz. Ondalık ayırıcı için virgül (",") ve ABD İngilizcesi olmayan tarih biçimleri kullanan İngilizce olmayan yerel ayarlar için jQuery doğrulamasını desteklemek için uygulamanızı genelleştirme adımlarını uygulamanız gerekir. Ondalık virgül ekleme yönergeleri için bu GitHub açıklama 4076'ya bakın.

Sonraki adımlar

Bir uygulamayı yerelleştirmek aşağıdaki görevleri de içerir:

Ek kaynaklar