dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.72k stars 1.07k forks source link

resource dll is not generating for China(zh-CN) in Linux when build the app #11423

Open dushmantha-plano opened 4 years ago

dushmantha-plano commented 4 years ago

I have been localizing our ASP .Net Core (2.1) MVC Project with Resource files and CookiesCultureRequest Culture pattern. We have 3 additional languages now such as Korean, Japanese and Chines.

The issue is when building the solution in the Linux deployment server. only Chines (zh-CN) folder and resource.dll of that locale have not been generated. But in my local Windows machine does all.

What should i do for forcing to generate the resource.dlls when building the solution. Both machines (my local and deployment) have same LOCALE LANGUE value (C.UTF-8).

cloud8666 commented 4 years ago

.net core 3.1 has same issue

dushmantha-plano commented 4 years ago

.net core 3.1 has same issue [https://github.com/aspnet/Mvc/issues/7307]

Please refer the above link. the issue is that "zh-CN" is not available in the Ubuntu Language Cultures. So you can use zh-Hans instead to work your localization in both platforms (Windows and Linux)

cwhsu1984 commented 4 years ago

hi, It took me a few hours to make Chinese display correctly. You can try the below code in your cshtml, and for your resource file use SomeResource.zh.resx.

// Startup.cs
    var supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("zh-CN"),
    }
// your cshtml
@inject IHtmlLocalizer<SomeResource> SomeLocalizer
<div>Login name place holder should be @SomeLocalizer["SomeResourceKey"]</div>
@{
    CultureInfo.CurrentUICulture = new CultureInfo("zh", false);
    <div>
        zh: @SomeLocalizer["SomeResourceKey"];
    </div>
}
0xced commented 3 years ago

Actually, this is a known issue with MSBuild, see https://github.com/dotnet/msbuild/issues/3897

EdiWang commented 3 years ago

.NET 5.0 has the same issue

nlogozzo commented 1 year ago

The same happens for oc-FR language code. oc resources dll is generated fine under Windows, but does not exist under linux. Using .NET 7

codelovercc commented 1 year ago

about zh-CN, use zh-hans-cn instead. And add a mapping config for transfer the alias to IETF name. Example if your app is asp.net core:


using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;

namespace My.Localization;

public sealed class IetfMappedRequestCultureProvider : RequestCultureProvider
{
    public override async Task<ProviderCultureResult?> DetermineProviderCultureResult(HttpContext httpContext)
    {
        // This line is not tested, I check the source code, RequestLocalizationOptions is not add in options, I'm not sure.
        // If so, you need make sure the property Options is set correctly. 
        Options ??= httpContext.RequestServices.GetService<RequestLocalizationOptions>();
        if (Options == null)
        {
            throw new InvalidOperationException("The RequestLocalizationOptions can not be null.");
        }

        ProviderCultureResult? result = null;
        foreach (var provider in Options.RequestCultureProviders.Where(provider =>
                     provider is not IetfMappedRequestCultureProvider))
        {
            if ((result = await provider.DetermineProviderCultureResult(httpContext)) is not null)
            {
                break;
            }
        }

        if (result is null)
        {
            return result;
        }

        // todo replace the code to real world config or options.
        // Key is the alias, Value is the IETF name. etc: {"zh-CN", "zh-hans-CN"}
        var mapper = new Dictionary<string,string>();
        var readOnlyMapper = mapper as IReadOnlyDictionary<string, string> ?? mapper.AsReadOnly();
        ReplaceWithMappedCulture(result.Cultures, readOnlyMapper);
        ReplaceWithMappedCulture(result.UICultures, readOnlyMapper);
        return result;
    }

    private static void ReplaceWithMappedCulture(IList<StringSegment> cultures,
        IReadOnlyDictionary<string, string> mapper)
    {
        for (var index = 0; index < cultures.Count; index++)
        {
            var c = cultures[index];
            // 处理映射
            if (!c.HasValue)
            {
                continue;
            }

            if (mapper.TryGetValue(c.Value.ToLowerInvariant(), out var realCulture))
            {
                cultures[index] = realCulture;
            }
        }
    }
}

app.UseRequestLocalization(options =>
{
    options.AddInitialRequestCultureProvider(new IetfMappedRequestCultureProvider { Options = options });
});
johnnyqian commented 1 month ago

.NET 6 has the same issue.