Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with globalization asp.net core 3.1 not getting value just key #18026

Closed
davidbuckleyni opened this issue Dec 25, 2019 · 13 comments
Closed
Assignees
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates investigate

Comments

@davidbuckleyni
Copy link

davidbuckleyni commented Dec 25, 2019

I have setup globalization as per the documents here but something must be wrong cause I am only getting the value of the key not the value of the resource.

Please find a short screencast video explaining this.

https://drive.google.com/file/d/1DaKvRlM9iRS5_1zvJjqTZlOE16UhhE6r/view

I am using the docs links here
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.1

The following is my code which i have more or less copied from the document link above.

// This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });

        services.Configure<RequestLocalizationOptions>(opts =>
        {
            var supportedCultures = new List<CultureInfo> { new CultureInfo("en-GB"), new CultureInfo("fr-FR"), };

            opts.DefaultRequestCulture = new RequestCulture("en-GB");

            // Formatting numbers, dates, etc.
            opts.SupportedCultures = supportedCultures;
            // UI strings that we have localized.
            opts.SupportedUICultures = supportedCultures;
        });
        // Add framework services.
        services.AddControllersWithViews()
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
            // Maintain property names during serialization. See:
            // https://github.com/aspnet/Announcements/issues/194
            .AddNewtonsoftJson(options =>
                options.SerializerSettings.ContractResolver = new DefaultContractResolver())
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix,
                opts => { opts.ResourcesPath = "Resources"; })
            .AddDataAnnotationsLocalization();
        services.Configure<ConnectionStringConfig>(Configuration);
        //lets inject the connection string to the data layer 
        //but we should be using the api layer for any heavy lifting.
        services.AddHttpClient("externalservice", c =>
        {
            // Assume this is an "external" service which requires an API KEY
            c.BaseAddress = new Uri("https://localhost:5001/");
        });
    
        // Add Kendo UI services to the services container
                    services.AddKendo();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        SetUpLocalization(app);

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
    
        app.UseRequestLocalization(options.Value);
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
        });


    }
    private static void SetUpLocalization(IApplicationBuilder app)
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en-US"),
            new CultureInfo("en-GB"),
            new CultureInfo("pl")
        };

        var options = new RequestLocalizationOptions
        {
            DefaultRequestCulture = new RequestCulture("en-GB", "en-GB"),
            SupportedCultures = supportedCultures,
            SupportedUICultures = supportedCultures,
         
        };
        options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
        {
            // My custom request culture logic
            return new ProviderCultureResult("en");
        }));

        // Find the cookie provider with LINQ
        var cookieProvider = options.RequestCultureProviders
            .OfType<CookieRequestCultureProvider>()
            .First();
        // Set the new cookie name
        cookieProvider.CookieName = "UserCulture";


        // Configure the Localization middleware
        app.UseRequestLocalization(options);




    }

This is my controller where I am accessing the resouce file key

public class StockController : Controller
{
    private  readonly IStringLocalizer<StockController> _localizer;
    
    RoundTableAPIClient apiClient = new RoundTableAPIClient();
    // GET

    public StockController(IStringLocalizer<StockController> localizer)
    {
      
        _localizer = localizer;
        
    }
    public IActionResult Index()  
    {
        var test = _localizer[ResourceKeys.StockPageTitle].Value;
        

        ViewBag.Title = _localizer["StockPageTitle"];

        return View();
    }
 }

But I am not getting the value that is in my resource file I am just getting the text StockPageTItle which is incorrect also how does one give the en-GB as default in asp.net core routes that is not explained in the docs. enter code here
enter image description here

Please note also this screenshot saying the following. I presume it's not finding the resource even though I have the naming correct my culture is en-GB by the way.

image

@pranavkm pranavkm added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Dec 26, 2019
@pranavkm pranavkm added this to the 5.0.0-preview1 milestone Dec 26, 2019
@pranavkm pranavkm self-assigned this Dec 26, 2019
@davidbuckleyni
Copy link
Author

Hi @pranavkm this is defo an issue No matter what i cannot get the resource file to show found and get the value of the key and not just the key.

@davidbuckleyni
Copy link
Author

I can give you Full access to my repo if u have a DevOps account and SQL database?

@davidbuckleyni
Copy link
Author

davidbuckleyni commented Dec 30, 2019

Hi @pranavkm Here is a full completed example of globalization not working in 3.1
Noticed.
1 Changing resource to be Public has no effect in 3.1 Ie U cant access resource in ResouceFolderName.ResouceKey
2. Using _localizer["TestResources"].Value; does not work either does it with or without the Value command it just retrieves the resource key I named the controller HomeController.en-GB.resx as standard has no effect cannot be found.

So please for the love of God tell me what I am doing wrong this needs looked at .

Full Git Repo
https://github.com/davidbuckleyni/LoalizationExampleMicrosoftCore31

@Metetron
Copy link

Hi,

I ran into a very similar problem. I have a lot of razor pages where I inject IStringLocalizers.
After the upgrade to 3.1 the rendered view just displays the key not the string that is defined in the resx- File.

I created a small sample containing two projects. Localization_Before targets asp.net core 2.2 and Localization_After targets asp.net core 3.1.
There are 2 strings displayed on the homepage in each project. One using the IViewLocalizer (this works in both projects) and using an IStringLocalizer injected into the page (this only works in asp.net core 2.2, in 3.1 only the key is displayed, not the resource).

Hope this helps :)

AspNetCoreLocalization.zip

@davidbuckleyni
Copy link
Author

@Metetron Thanks hopefully they be able to understand this is a issue in 3.1 I created a project with all the suggestions made on so but none of them work localization is def broken in terms of 3.1 we just need them to admit it.

@davidbuckleyni
Copy link
Author

@Metetron That means IStringLocater is defo broke in 3.1 and no our project is 3.1 so need this working

@davidbuckleyni
Copy link
Author

@Metetron I noticed also your example only uses views and not controllers I believe that there is an issue in controllers as well according to my github

@davidbuckleyni
Copy link
Author

I am still getting blank with this method brand new asp.net 2.0 project

private readonly IStringLocalizer _localizer;

    public HomeController(IStringLocalizer<HomeController> localizer)
    {
        _localizer = localizer;


    }

    public IActionResult Index()
    {
        var TEST = _localizer["Title"];

return View();
    }

@Metetron
Copy link

#17733 is the same as my issue. I tried the proposed workaround of moving the SharedResources.cs- File out of the resources folder and it worked.

@davidbuckleyni For testing I added a controller and a view into my test project and was able to reproduce your exact issue. The workaround mentioned above also worked here.

Nevertheless I hope this gets fixed.

I published my example project here: https://github.com/Metetron/AspNetCore3.1-Localization-Issue

@davidbuckleyni
Copy link
Author

:Metetron I totally agree I would look at it myself If I could but im not part of the team.

@davidbuckleyni
Copy link
Author

@Metetron Also the accessability of being able to do Resources.ResourceName to get the value from the default resource appears to be broken as well.

@davidbuckleyni
Copy link
Author

davidbuckleyni commented Dec 31, 2019

@Metetron was having a look a the source I see an interface for IHtml I View but not STRING could they have forgotten to carry this over I doubt that. @pranavkm

image

@davidbuckleyni
Copy link
Author

Solved this It ended being I had to add the following I re did my Project.

var supportedCultures = new string[] { "en-GB", "fr-FR" };
app.UseRequestLocalization(options =>
options
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures)
.SetDefaultCulture("en-gb")
.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context =>
{
return Task.FromResult(new ProviderCultureResult("en-gb"));
}))
);

Also, I don't believe the above step was in the documentation i believe it needs to be adjusted.

image

@ghost ghost locked as resolved and limited conversation to collaborators Feb 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates investigate
Projects
None yet
Development

No branches or pull requests

3 participants