13

According to the documentation:

The runtime doesn’t look up localized strings for non-validation attributes. In the code above, “Email” (from [Display(Name = "Email")]) will not be localized.

I'm looking for a way to localize text in DisplayAttribute. Any suggestions to do it in a proper way(s)?

David
  • 400
  • 2
  • 4
  • 17
  • To concerned modern readers like me who happen to arrive here: this is not an issue in later versions of the framework. As Microsoft states, "In ASP.NET Core MVC 1.1.0 and higher, non-validation attributes are localized." – MarredCheese Oct 23 '20 at 01:57

5 Answers5

13

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:

enter image description here

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)

enter image description here

Shimmy Weitzhandler
  • 92,920
  • 119
  • 388
  • 596
Sock
  • 4,963
  • 19
  • 29
  • 1
    It seems odd that non-validation attributes are not localized according to this new asp.net core localization mechanism. Do you think it is possible implement it for non-validation attributes too, or is there a reason that mvc guys skipped non-validation attributes? – David Jun 18 '16 at 16:45
  • I agree, it is a bit odd! I assume there must be a reason why they decided not to but I'm not sure off the top of my head. You could always ask on GitHub and see what they say. – Sock Jun 19 '16 at 17:15
  • 3
    I'm getting `The type or namespace 'MyResources' could not be found`. What am I missing? – Lucius Aug 02 '16 at 10:02
  • 1
    Hello, I'm using .NET Core 1.0.0 and this implementation throws the following error: InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type '' is not public or does not contain a public static string property with the name 'RememberMe'. Does anybody have any experience with this error? – Vladislav Sep 02 '16 at 10:25
11

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.

This is how a Central Location for String Localization

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

Rahma Samaroon
  • 593
  • 8
  • 9
7

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.

[https://i.imgur.com/q3BK8T5.png]

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

enter image description here

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.

enter image description here

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

Prolog
  • 1,901
  • 1
  • 12
  • 24
2

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.

holmescn
  • 1,010
  • 10
  • 17
  • Works as expected, thanks.. after many hours spend, i see your answer and it works like a charm !! – vivek ramasamy Nov 26 '20 at 07:41
  • I'm looking for similar solution for even declaring Display. Because most of the time, the property name is display name, we should be able to declare [Display] [EmailAddress] public string Email { get; set; } This should automatically use the property name 'Email' to translate – SKCS Kamal Feb 25 '21 at 18:09
1

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).

feradz
  • 1,176
  • 1
  • 14
  • 26