Aug 29, 2018

ASP.NET Core localization - Shared resources - simplest scenario RePost

I need one simple shared resource file for placing my label and error text in one place. There is no need for localization but resource file is best choice.

I've picked only bare minimum from this post:

https://damienbod.com/2017/11/01/shared-localization-in-asp-net-core-mvc/

Currently I'm working on ASP.NET Core 2.1

1. Create Resources folder in your Web project and inside create SharedResources.resx. Select from access modifier of resource file designer "Public".

2. Create override of localization factory as explained in above post:

public class CustomLocalizationService
    {
        private readonly IStringLocalizer _localizer;
        public CustomLocalizationService(IStringLocalizerFactory factory)
        {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(nameof(SharedResource), assemblyName.Name);
        }
        public LocalizedString Get(string key)
        {
            return _localizer[key];
        }
    }
3. Register your new service in Startup:

     public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<CustomLocalizationService>();
            services.AddLocalization(options => options.ResourcesPath = "Resources");

4. Fix MVC options to support view localization and support for Data annotations error messages:

services.AddMvc()
                .AddViewLocalization()
                .AddDataAnnotationsLocalization(options =>
                  {
                      options.DataAnnotationLocalizerProvider = (type, factory) =>
                      {
                          var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
                          return factory.Create(nameof(SharedResource), assemblyName.Name);
                      };
                  }); 
5. Finally when using in View you must use your new localization wrapper:

@inject CustomLocalizationService SharedLocalizer

Data annotations should look like this:

[StringLength(200, ErrorMessageResourceName = "ValidationErrorTooLongText", ErrorMessageResourceType =typeof(SharedResource))]

For some reason I couldn't use dot in my resource key naming so instead of:

Validation.Error.TooLongText

; I had to write:

ValidationErrorTooLongText