2

Am trying to get a very simple, console app to work with localizing and TryValidateObject on my object.

I have a Student class:

 public class Student
    {
        [Display(ResourceType = typeof(Strings), Name = @"Student_Name_DisplayName")]
        [Required]
        public string Name {get; set;}
    }

I have a public resource Strings.resx for my default language (English) with

Key = Student_Name_DisplayName
Value = Name

I have an internal resource file Strings.es.resx for Spanish

Key = Student_Name_DisplayName
Value = Nombre

If I create a new Student object and do not set the Name property to something, I expect to see an error if I call Validator.TryValidateObject. I do.

Setting the current Culture and UI Culture to English, I get the validation error: "The Name field is required."

Setting the current Culture and UI culture to Spanish, I get the validation error: "The Nombre field is required."

Pretty close, but I'd like the rest of the message to be in Spanish as well.

I've found that doing this in Silverlight works - Silveright somehow "sees" the right language and gets me the right error. However, I have some server-side processing I'd also like to have return the proper translated string.

The full code is below:

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");

Student student  = new Student();
var validationResults = new Collection<ValidationResult>();

Validator.TryValidateObject(student, new ValidationContext(student, null, null), validationResults, true);

if (validationResults.Count > 0)
  Debug.WriteLine(validationResults[0].ErrorMessage);
//produces "The Name field is required"    

validationResults.Clear(); 

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("es");
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("es");

Student student2 = new Student();
Validator.TryValidateObject(student2, new ValidationContext(student2, null, null), validationResults, true);

if (validationResults.Count > 0)
  Debug.WriteLine(validationResults[0].ErrorMessage);
  //produces "The Nombre field is required"

Thoughts?

Thanks (Gracias)

Don B
  • 53
  • 5

3 Answers3

0

You need to specify values for the localization properties of the [Required] attribute (e.g. ErrorMessageResourceName).

See http://haacked.com/archive/2009/12/11/localizing-aspnetmvc-validation.aspx

RobSiklos
  • 8,348
  • 5
  • 47
  • 77
  • Going through Silverlight's validation (via databinding to XAML) I find that Silverlight does give the correct message in a case like this, completely translated, without having to provide any parameters in the Required attribute. Obviously, it goes through some other layer of translation that straight .Net as I've written it does not. I wonder what that layer is? (Thanks for the example link - it works if you don't need to say the name of the field in the "required" error message. At this point, I would like to do that if possible. Thanks. – Don B Sep 05 '13 at 18:39
0

Silverlight seems to ship with all the localized resources, but the .NET framework does not.

Try installing the .NET Language Pack (for .NET 4.5: http://www.microsoft.com/en-us/download/details.aspx?id=30667)

RobSiklos
  • 8,348
  • 5
  • 47
  • 77
0

You will need to read the property name using these lines

var context = new ValidationContext(parseResult.ProductVM, serviceProvider: null, items: null);
List<ValidationResult> validationResults = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(parseResult.ProductVM, context, validationResults, true);
if (!isValid)
{
    string memberName = validationResults.FirstOrDefault().MemberNames.FirstOrDefault();
    string displayName = GeneralHelper.GetDisplayNameByMemberName<ViewModels.ProductVM>(memberName);
    string displayNameTranslated = resourceManager.GetString(displayName, MultiLangHelper.CurrentCultureInfo);   
}

Then continue the answer here to get the translated name / the value from .resx files

https://stackoverflow.com/a/64524358/1594274

**parseResult.ProductVM is my view model

**GetDisplayNameByMemberName is mentioned in my other answer in the link above

**The resourceManager

ResourceManager resourceManager = new System.Resources.ResourceManager(typeof(App_GlobalResources.Pages));
Adel Mourad
  • 1,351
  • 16
  • 13