2016-07-01 16 views
8

Tôi đang cố gắng xây dựng một ứng dụng ASP.NET Core cần có sẵn bằng tiếng Anh và tiếng Đức. Vấn đề của tôi là IViewLocalizer luôn trả về văn bản tiếng Đức, ngay cả với văn hóa được đặt thành tiếng Anh. Làm cách nào để tôi có được văn bản phù hợp cho văn hóa hiện tại?IViewLocalizer trả về sai ngôn ngữ

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> 

File Resource tọa lạc tại Resources\Views.Home.Index.de.resx

Dự kiến ​​ou tput:

 
Hello, World! 

CurrentCulture: en 
CurrentUICulture: en 

Trang đầu ra:

 
Hallo Welt! 

CurrentCulture: en 
CurrentUICulture: en 

Request Headers:

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

Bạn có thể chia sẻ cách yêu cầu trông giống như bao gồm tiêu đề không? –

+0

Tôi đã mở một vấn đề tại https://github.com/aspnet/Localization/issues/277 nhưng chúng tôi cần một repro. Bạn có thể cung cấp nó? – RickAndMSFT

+0

Xem https://github.com/aspnet/Localization/issues/277 không repro, có vẻ như hoạt động chính xác. – RickAndMSFT

Trả lời

0

Nếu bất cứ ai đang có vấn đề này với ASP.NET lõi 1.1 hoặc mới hơn, hãy thử thêm <NeutralLanguage>YOUR_DEFAULT_LANGUAGE</NeutralLanguage>-.csproj của bạn như thế này:

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

Nó giải quyết vấn đề của tôi và nó hiện đang làm việc một cách chính xác.

4

tôi đã cùng một vấn đề từ hôm qua. Có vẻ như LocalizationProvider không đặt đúng văn hóa. Sau khi triển khai LocalizationProvider tùy chỉnh, IViewLocalizer cũng bắt đầu hoạt động hoàn hảo cho ViewsViewComponents.

Ngoài ra tôi đã phải thực hiện các ngôn ngữ vào url theo cách sau:

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

Dưới đây là những gì tôi đã làm:

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

Trong phương thức ConfigureServices tôi đã thêm CultureToUrlActionFilter(). Nó lấy mã ngôn ngữ 2 ký tự từ url và đặt chính xác CultureInfo. Nếu Url chứa một mã văn hóa không được phép, nó sẽ chuyển hướng đến văn hóa mặc định.

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

Trong phương pháp Configure tôi thiết lập các nhà cung cấp nội địa hóa tùy chỉnh và chèn nó như là đầu tiên trong hàng đợi nhà cung cấp:

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

Nếu url chứa không có mã văn hóa sau tên miền, tôi làm một Chuyển hướng đến http://somedomain/<2-letter-culture-code> (với văn hóa mặc định). Các url luôn phải có văn bản được chỉ định.

Tuyến đường:

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

tôi sự chuyển hướng nó trong HomeController, Chuyển động

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

Các file resx đều nằm trong cùng một thư mục /Resources/Views.Home.Index.en.resx /Resources/Views.Home.Index.de.resx /Resources/Views.Shared.Components.Navigation.Default.en.resx vv

+0

Tôi đã mở một vấn đề tại https://github.com/aspnet/Localization/issues/277 nhưng chúng tôi cần một repro. Bạn có thể cung cấp điều đó không? – RickAndMSFT

+0

https://github.com/aspnet/Localization/issues/277 không repro, có vẻ như nó hoạt động chính xác. – RickAndMSFT

+0

Bạn đang nhắm mục tiêu theo khuôn khổ nào? Trên máy tính để bàn, Asp.Net Core yêu cầu nhắm mục tiêu .NET 4.6 trở lên để lưu lượng văn bản chính xác qua các cuộc gọi không đồng bộ. Điều này không áp dụng nếu bạn đang nhắm mục tiêu .NETCoreApp1.0 – Pranav

Các vấn đề liên quan