0

I am trying to use localization with the data model annotations.

Update: added example code and changed the example to reflect the code

I have prepared a small non-working example which can be cloned from here https://bitbucket.org/feradz/dataannotationlocalization.git

To load the page browse to http://localhost:6092/PersonalInfo/Edit

I have the following class:

public class PersonalInfo 
{
    [Display(Name = "NameDisplay", ResourceType = typeof(PersonalInfo))]
    [Required(ErrorMessageResourceName = "NameRequired", ErrorMessageResourceType = typeof(PersonalInfo))]
    public string Name { get; set; }
}

I have created DataAnnotationLocalization.ViewModels.Member.PersonalInfo.resx and DataAnnotationLocalization.ViewModels.Member.PersonalInfo.es.resx resource files in directory Resources.

In DataAnnotationLocalization.ViewModels.Member.PersonalInfo.resx and DataAnnotationLocalization.ViewModels.Member.PersonalInfo.es.resx I have defined NameDisplay=Name EN and NameDisplay=Name ES respectively.

When I try to load the page I get the following error.

An unhandled exception occurred while processing the request.

InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type 'DataAnnotationLocalization.ViewModels.Member.PersonalInfo' is not public or does not contain a public static string property with the name 'resourceNameKey'.
System.ComponentModel.DataAnnotations.LocalizableString.<>c__DisplayClass12_0.<GetLocalizableValue>b__1()

Is there any out-of-the-box support for this in ASP.NET 5 MVC6?

2 Answers 2

2

The resource is it looking in is your class, and not your resource, because the resource and the class have the same name:

public class PersonalInfo
{
    [Display(Name = "resourceNameKey", ResourceType = type(PersonalInfo))]
    public Title { get; set; }
}

You can fix this by explicitly saying the namespace:

public class PersonalInfo
{
    [Display(Name = "resourceNameKey", ResourceType = type(Namespace1.Namespace2.PersonalInfo))]
    public Title { get; set; }
}

UPDATE

To make your example work:

namespace DataAnnotationLocalization.ViewModels.Member
{
    public class PersonalInfo
    {
        [Display(Name = "NameDisplay", ResourceType = typeof(DataAnnotationLocalization.Resources.DataAnnotationLocalization_ViewModels_Member_PersonalInfo))]
        [Required(ErrorMessageResourceName = "NameRequired", ErrorMessageResourceType = typeof(DataAnnotationLocalization.Resources.DataAnnotationLocalization_ViewModels_Member_PersonalInfo))]
        public string Name { get; set; }
    }
}

Best would be if you rename your resource files so the names won't be confused with the class name you are using it in.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, unfortunately this still does not work for me. I have prepared a git repo with a small not-working example. It would be great if you can have a look. https://bitbucket.org/feradz/dataannotationlocalization.git
Resource files generate designtime classes. You need to reference those classes, if you select the class you said and do "rightclick => Go to definition" you would end up in the same file as you started. With my change, you end up in the resource file
Ok, now this works. I was confused from this example http://damienbod.com/2015/10/21/asp-net-5-mvc-6-localization/ that the resource file name should be same as the class name. With this the framework is able to transparently and automatically locate it.
1

Problem is in Resource class.

If you use Visual studio for adding resources, it will generate Resource class with internal class modifier and internal properties' modifier for each resource key.

Quick fix: You should open resource class (has same name as the resource file with appended 'Designer.cs') and change 'internal' to 'public'. And you must do it every time when you add new key into resource file. This is bug in Visual Studio 2015.

1 Comment

Thanks, this was also part of the problem!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.