11

I've a fully localized website, which is in mostly in french/english/german.

For now, all was going fine, but I did notice a problem with some error message of asp.net MVC.

I've one property in my model:

[Required]
[LocalizedDisplayName("PublicationDate", NameResourceType = typeof(LocalizationResources.Views.Composer.BaseInfoForm))]
public DateTime PublicationDate { get; set; }

LocalizedDisplayname is an extension of the DisplayNameAttribute, which goes in the Resx file to get the correct translation

The thread CurrentCulture and the CurrentCultureUI are in fr-FR, so the message should be displayed in french(like it does with my [Required] Attribute, display automatically "Le champ Publication est requis".

But in the case of a DateTime, if I enter something which isn't a date, the validator just returns me a "The value 'asdfasdf' is not valid for Publication." So:

  • Why MVC returns me sometimes error message in french, and sometimes in english, in the same form(and I precise, it's the default error message)
  • How to replace this message genericly, by indicating a text like "La valeur {0} n'est pas une date valide pour le champ {1}"

Thank you very much

J4N
  • 19,480
  • 39
  • 187
  • 340

4 Answers4

7

I think these answer your two questions:

  • Why MVC returns me sometimes error message in french, and sometimes in english, in the same form(and I precise, it's the default error message)

One notable difference is that the [Required] attribute performs explicit client-side validation, whereas when your field does not contain a valid DateTime, you get server-side validation through a failure by the default model binder to create a DateTime object from the posted form data. It's quite a different mechanism, which I guess explains the different outcome. It would have been nice if the outcome had been consistent, of course.

  • How to replace this message genericly, by indicating a text like "La valeur {0} n'est pas une date valide pour le champ {1}"

There are two ways:

  1. Tell the default model binder what resource string to use for the error message using the DefaultModelBinder.ResourceClassKey property. See the answer to this related question for a description of how to achieve this (for MVC 2 but it hasn't changed in MVC 3)
  2. A nicer method (I think) is to do client-side validation. This allows you to provide the error message string you wish from your localized resources. Do it by adding a DataType attribute as per below, assuming you created a resource class called MyLocalizedResources with a string having key DateTimeFormatValidationMessage translated in French as "La valeur {0} n'est pas une date valide pour le champ {1}":

    [Required]
    [DataType(DataType.Date, ErrorMessageResourceType = typeof(MyLocalizedResources), ErrorMessageResourceName = "DateTimeFormatValidationMessage")]
    [LocalizedDisplayName("PublicationDate", NameResourceType = typeof(LocalizationResources.Views.Composer.BaseInfoForm))]
    public DateTime PublicationDate { get; set; }
    
Community
  • 1
  • 1
Clafou
  • 15,250
  • 7
  • 58
  • 89
  • Thanks. Since all my localizable string are in a different DLL, I can't use the `1.` . So I will use the second one. Thank you very much for the answer! – J4N Jun 12 '12 at 06:59
  • I maybe have accepted the answer too soon, I put the DataType attribute, exactly how you stated, but I still have the old message when my type isn't a date – J4N Jul 03 '12 at 08:40
  • 1
    There are other attributes for other datatypes. For example I have this to show localized error messages for a required email text field: [Required(ErrorMessageResourceType = typeof(Shared), ErrorMessageResourceName = "RequiredFieldValidationMessage", ErrorMessage = null)] [EmailAddress(ErrorMessageResourceType = typeof(Shared), ErrorMessageResourceName = "EmailFormatValidationMessage", ErrorMessage = null)] public string Email { get; set; } – Clafou Jul 03 '12 at 08:43
  • It's still for DateTime fields – J4N Jul 03 '12 at 09:01
  • Oh sorry I misunderstood your comment. Are you sure the satellite assembly is deployed correctly, and the ErrorMessageResourceType and ErrorMessageResourceName are correct? A quick way to make sure it's not a deployment/satellite assembly issue would be to load the resource string in code. – Clafou Jul 03 '12 at 13:55
1

ASP.NET MVC framework does couple of implicit validations: one is required validation and the other one is whether the value is valid for the property or not kind of validation and this two happens eventhough we doesn't decorate the properties with data-annotations.

You have to create keys for PropertyValueInvalid and PropertyValueRequired in your global resource class.

This thread will help you Globally localize validation

Community
  • 1
  • 1
VJAI
  • 32,167
  • 23
  • 102
  • 164
1

I had same problem, same project structure. I finally used conventions of MVC, try this way.

I replaced all [Required] data annotations with

[Required(ErrorMessageResourceName = "Common_Mandatory_Field", ErrorMessageResourceType = typeof(MyExternalDllResources.Language))]

In resource string "Common_Mandatory_Field" is defined in this way, examples: Italian resource file:: Il campo {0} è obbligatorio.

English resource file:: The {0} field is required.

Japan resource file:: {0} フィールドが必要です。

MVC will replace {0} with the name of [Display] data annotation value of the associated control, translated if in case. If you do not provide a [Display] data annotation the property definition will be used.

0

You can localize your custom validation attributes. Also you localize ASP.NET MVC built-in attributes.

Like [Required] attribute.

An Example:

[LocalizedRequired(ErrorMessage = "You must specify an email address")] 
string SomeProperty { get; set; }

And you can just override Required property:

public class LocalizedRequiredAttribute: RequiredAttribute
{
    public override string FormatErrorMessage(string name)
    {
        return LocalizedString(ErrorMessage, name);
    }
}

The reasone to shown up in differen languages is : I think mvc get culture code of current user in client side.

gandil
  • 5,398
  • 5
  • 24
  • 46
  • Not at all.. like I said, the Thread locale is fr-FR. And other message were in correct language. Even client side texts are generated server side with the server locale. (and by default I set the thread culture to the browser culture) – J4N Jun 12 '12 at 07:01