ASP.NET Core DisplayAttribute Localization

旧城冷巷雨未停 提交于 2019-12-01 16:59:30

You can set the ResourceType on the DisplayAttribute which can be used to localize your text.

Add a resource .resx file to your project e.g. MyResources.resx, and add a resource for your field:

Then reference the name of the field and the MyResources type in your DisplayAttribute

[Display(Name = "RememberMe", ResourceType  = typeof(MyResources))]
public bool RememberMe { get; set; }

The localized resource will be pulled through automatically (see the text box)

Note: there is currently a bug in RC2 which will throw a NotImplementedException if you use non-latin characters in your resource values: https://github.com/aspnet/Razor/issues/760

Having a Central location for all your localization whether in view or dataannotations is the best approach I can think of, and this how I got to work. In Startup.cs file after you installed nuget packages for localization add the following code

services.AddMvc().AddViewLocalization().AddDataAnnotationsLocalization(options => 
    options.DataAnnotationLocalizerProvider = (type, factory) => new StringLocalizer<Resources>(factory));

services.Configure<RequestLocalizationOptions>(options => {
   var cultures = new[]
   {
       new CultureInfo("en"),
       new CultureInfo("ar")
   };
   options.DefaultRequestCulture = new RequestCulture("en", "en");
   options.SupportedCultures = cultures;
   options.SupportedUICultures = cultures;
});

This way the DataAnnotationLocalizerProvider will be from the Resources.{culture}.rex -( The Resource file must have an access modifier of No code gen)- assuming that no resources will be needed for the default language, and to be able to access the resource file since no code will be generated and empty class with the same name must be created.

and in _ViewImports.cshtml file inject the following

@inject IHtmlLocalizer<Resources> Localizer

by doing this you now have a global variable Localizer to be used in any of the views for localization purposes.

you can find further information on Globalization and localization in ASP.NET Core

Actually I found an simple solution for the followers. The display name in most of time is used in the label of an input field. So do this if you like:

<label asp-for="Email">@Localizer["Email"]</label>

of course, you can pass the property name by @Html.DisplayNameFor, but most of time, this one already works well.

For those who struggle (@lucius, @vladislav) with error:

Cannot retrieve property 'Name' because localization failed. Type 'Xxxx.EmployeeResx' is not public or does not contain a public static string property with the name 'FirstName'.

It is caused by access modifier on .resx files which is by default set to Internal (in my case it was No code generation). Change it to public in Access Modifier dropdown in the resource file toolbar.

After that you should be able to see the properties from the resource type:

Also, consider not using special signs in field names as they are a basis for auto-generated C# property names. The field names are converted into C# friendly names and that is why you can end up with inconsistency between name of resource file field and name of auto-generated property. Best to avoid any hyphens - or dots . Underscores _ are fine. You can always look up how the auto-generated properties look like in resource_file_name.Designer.cs class under the related resource file.

Many thanks to Bala Murugan who wrote a good article concerning this topic on Code Digest.

I have just created a project which demonstrates localization including localization of Display attribute for class properties as well as enums.

The project can be found here https://github.com/feradz/ASPNetCoreLocalization/wiki

The Display attribute has to be localized using the approach prior to ASP.NET Core 1.0. Have a look at the DataAnnotations.resx file in the project.

The Name property of Display cannot contain empty spaces, and special characters.

[Display(Name = "NoSpacesAndSpecialChanractersHere", ResourceType = typeof(Resources.DataAnnotations))]
public string FirstName { get; set; }

ResourceType should be the fully qualified resource class name (i.e. including the name space).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!