2016-07-01 12 views
8

Próbuję utworzyć aplikację ASP.NET Core, która powinna być dostępna w języku angielskim i niemieckim. Mój problem to IViewLocalizer zawsze zwraca tekst w języku niemieckim, nawet przy ustawieniu kultury na angielski. Jak uzyskać odpowiedni tekst do aktualnej kultury?IViewLocalizer zwraca nieprawidłowy język

Startup.cs

public void ConfigureServices(IServiceCollection services) 
{  
    services.AddLocalization(opt => opt.ResourcesPath = "Resources"); 
    services.AddMvc() 
     .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    var cultures = new[] { new CultureInfo("en"), new CultureInfo("de") }; 
    app.UseRequestLocalization(new RequestLocalizationOptions 
    { 
     DefaultRequestCulture = new RequestCulture("en"), 
     SupportedCultures = cultures, 
     SupportedUICultures = cultures     
    }); 

    app.UseMvc(routes => 
    { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 

HomeController.cs

public class HomeController : Controller 
{ 
    public IActionResult Index() 
    { 
     return View(); 
    } 
} 

Index.cshtml

<!DOCTYPE html> 
@using Microsoft.AspNetCore.Mvc.Localization; 
@inject IViewLocalizer Localizer 
<html> 
    <body> 
     <h1>@Localizer["Hello, World!"]</h1> 
     <ul> 
      <li>CurrentCulture: @System.Globalization.CultureInfo.CurrentCulture</li> 
      <li>CurrentUICulture: @System.Globalization.CultureInfo.CurrentUICulture</li> 
     </ul> 
    </body> 
</html> 

Resource Plik znajduje się na Resources\Views.Home.Index.de.resx

Oczekiwany ou tput:

 
Hello, World! 

CurrentCulture: en 
CurrentUICulture: en 

wyjście Strona:

 
Hallo Welt! 

CurrentCulture: en 
CurrentUICulture: en 

Żądanie Nagłówki:

GET/HTTP/1.1 
Host: localhost:61904 
Connection: keep-alive 
Cache-Control: max-age=0 
Upgrade-Insecure-Requests: 1 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-US,en;q=0.8,es;q=0.6,de;q=0.4 
+0

Czy możesz udostępnić sposób wyświetlania żądania, w tym nagłówki? –

+0

Otworzyłem problem na https://github.com/aspnet/Localization/issues/277, ale potrzebujemy repro. Czy możesz to dostarczyć? – RickAndMSFT

+0

Zobacz https://github.com/aspnet/Localization/issues/277 no repro, wygląda na to, że działa poprawnie. – RickAndMSFT

Odpowiedz

0

Jeśli ktoś jest o ten problem z ASP.NET 1.1 lub nowszym rdzeniu, spróbuj dodać <NeutralLanguage>YOUR_DEFAULT_LANGUAGE</NeutralLanguage> do swojej .csproj tak:

<PropertyGroup> 
<TargetFramework>netcoreapp1.1</TargetFramework> 
<ApplicationIcon /> 
<Win32Resource /> 
<NeutralLanguage>en</NeutralLanguage> 
</PropertyGroup> 

się rozwiązać mój problem i to teraz działa poprawnie.

4

miałem ten sam problem od wczoraj. Wygląda na to, że LocalizationProvider nie może ustawić poprawnej kultury. Po wdrożeniu niestandardowego LocalizationProvider, IViewLocalizer zaczął działać również doskonale dla Views i ViewComponents.

Również miałem do wdrożenia języku, na adres URL w następujący sposób:

http://somedomain.com/<2-letter-iso-language-name>/controller/action

Oto co zrobiłem:

Startup.cs

public static string defaultCulture = "uk-UA"; 

public static List<CultureInfo> supportedCultures 
{ 
    get 
    { 
     return new List<CultureInfo> { 
      new CultureInfo("en-US"), 
      new CultureInfo("uk-UA"), 
      new CultureInfo("de-DE") }; 
    } 
} 

W metodzie ConfigureServices dodałem CultureToUrlActionFilter(). Wyszukuje dwuliterowy kod języka z adresu url i ustawia poprawną CultureInfo. Jeśli adres URL zawiera niedozwolony kod kultury, przekierowuje do domyślnej kultury.

public void ConfigureServices(IServiceCollection services) 
{ 
    services 
     .AddLocalization(options => options.ResourcesPath = "Resources") 
     .AddMvc(options => { options.Filters.Add(new CultureToUrlActionFilter()); }) 
     .AddViewLocalization() 
     .AddDataAnnotationsLocalization(); 
} 

W metodzie Konfiguracja skonfigurować dostawcy niestandardowej lokalizacji i wstawia go jako pierwszy w kolejce provider:

var options = new RequestLocalizationOptions() { 
    DefaultRequestCulture = new RequestCulture(defaultCulture), 
    SupportedCultures = supportedCultures, 
    SupportedUICultures = supportedCultures }; 
options.RequestCultureProviders.Insert(0, new UrlCultureProvider()); 
app.UseRequestLocalization(options); 

Jeśli adres URL zawiera żadnego kodu Kultury po nazwie domeny, robię Przekieruj do http://somedomain/<2-letter-culture-code> (do domyślnej kultury). Adresy URL zawsze muszą mieć określoną kulturę.

Trasy:

app.UseMvc(routes => { 
    routes.MapRoute("home_empty", "", defaults: new { culture="", controller = "Home", action = "Redirect" }); 
    routes.MapRoute("home", "{culture}", defaults: new { controller = "Home", action = "Index" }); 

zrobić to przekierować go w HomeController, Przekierowanie akcję przy

HomeController.cs

public IActionResult Redirect() { 
    return RedirectToAction("Index", new { culture = Startup.defaultCulture }); 
} 

UrlCultureProvider.cs

using Microsoft.AspNetCore.Localization; 
using System; 
using System.Threading.Tasks; 
using Microsoft.AspNetCore.Http; 
using System.Globalization; 

namespace astika.Models 
{ 
public class UrlCultureProvider: IRequestCultureProvider { 

    public Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) 
    { 
     if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); 
     var pathSegments = httpContext.Request.Path.Value.Trim('/').Split('/'); 

     string url_culture = pathSegments[0].ToLower(); 

     CultureInfo ci = Startup.supportedCultures.Find(x => x.TwoLetterISOLanguageName.ToLower() == url_culture); 
     if (ci == null) ci = new CultureInfo(Startup.defaultCulture); 

     CultureInfo.CurrentCulture = CultureInfo.CurrentUICulture = ci; 

     var result = new ProviderCultureResult(ci.Name, ci.Name); 
     return Task.FromResult(result); 
    } 
} 
} 

CultureToUrlActionFilter.cs

using Microsoft.AspNetCore.Mvc; 
using Microsoft.AspNetCore.Mvc.Filters; 
using Microsoft.AspNetCore.Routing; 
using System; 
using System.Globalization; 

namespace astika.Models 
{ 
public class CultureToUrlActionFilter : IActionFilter 
{ 
    public void OnActionExecuted(ActionExecutedContext context) { } 

    public void OnActionExecuting(ActionExecutingContext context) 
    { 
     bool redirect = false; 
     string culture = context.RouteData.Values["culture"].ToString().ToLower(); 

     redirect = String.IsNullOrEmpty(culture); 

     if (!redirect) 
     { 
      try 
      { 
       CultureInfo ci = new CultureInfo(culture); 
       redirect = Startup.supportedCultures.FindIndex(x => x.TwoLetterISOLanguageName.ToLower() == culture) < 0; 
      } 
      catch 
      { 
       redirect = true; 
      } 
     } 


     if (redirect) 
     { 
      CultureInfo cid = new CultureInfo(Startup.defaultCulture); 
      context.Result = new RedirectToRouteResult(new RouteValueDictionary(new { culture = cid.TwoLetterISOLanguageName, controller = "Home", action = "Index" })); 
     } 
    } 
} 
} 

W RESX pliki są zlokalizowane w tym samym folderze /Resources/Views.Home.Index.en.resx /Resources/Views.Home.Index.de.resx /Resources/Views.Shared.Components.Navigation.Default.en.resx etc

+0

Otworzyłem problem na https://github.com/aspnet/Localization/issues/277, ale potrzebujemy repro. Czy możesz to zapewnić? – RickAndMSFT

+0

https://github.com/aspnet/Localization/issues/277 no repro, wygląda na to, że działa poprawnie. – RickAndMSFT

+0

Jakie ramy są kierowane? Na komputerze stacjonarnym Asp.Net Core wymaga kierowania na platformę .NET 4.6 lub nowszą, aby poprawnie przepływać kulturami przez połączenia asynchroniczne. Nie dotyczy to sytuacji, gdy kierujesz na .NETCoreApp1.0 – Pranav

Powiązane problemy