locked
Change default validation messages RRS feed

  • Question

  • User150963435 posted

    Hi All,

    I'm facing a problem with validation messages. I have a datetime field validated by MVC framework. When the user enters a bad formatted date, it tells him to change to a good formatted date in english. But my web site is not english ! How can I change default messages and make theim more user friendly please ?

    Thanks

    Friday, January 8, 2010 12:30 PM

Answers

  • User-1032240251 posted

    This is a strong hint that you should use view models for binding between controller and view, and not your business objects.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 12:13 PM
  • User150963435 posted

    Ok but I think this is not a solution about validation messages from Framework.

    I had the same problem with WPF and validation messages. Whatever the method you use (IDataErrorInfo, Validation into Service Layer, DataAnnotations...) the default message sent by the framework (WPF or ASP.net MVC) will be there. It's an exception thrown during the validation of the form when it tries to fill the DateTime property (or every type you want) with a bad value (like text or something else, but not in the good format). The framework, catching the exception, will automatically generate a validation message telling that the value isn't in good format.

    With WPF, I found a solution using Validation with raw values before the framework tries to fill the property so I can handle it myself and return a message of my own in the good language.

    To make long story short : Try to create a new MVC projet, add a simple class with a datetime property, add a Create action and its view (strongly typed to your class).

    Now test the creation of a new object trough the form. If you type a wrong formatted date, you will see a validation message : "wrong value for blabla". Now place a breakpoint on the Create action open bracket ("{") and retry to type a wrong date. When you reach to the breakpoint, add a watch to this.modelstate and try to see if there is an error on your property name, you will see that there is an error.

    So my question is : with my little example, you have seen that a default english message is stored into the modelstate errors BEFORE you can do anything. So if it's before anything, why a view model, a service layer or whatever you want could handle this error and manage the message before the framework do ? (if you have a concrete example, I would be glad to see it because I really really have no idea about how to handle it)


    Thanks for your reply.

    BR

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 12:30 PM
  • User-1032240251 posted

    Ah, what you're talking about here isn't validation, but model binding failures. You can use resources for this message.

    Create a global resource class in App_GlobalResources, and set DefaultModelBinder.ResourceClassKey to the name of this class (for example, if you made "Messages.resx", then set ResourceClassKey to "Messages").

    There are two strings you can override in MVC 2:

    • The string value for "PropertyValueInvalid" is used when the data the user entered isn't compatible with the data type (for example, typing in "abc" for an integer field). The default message for this is: "The value '{0}' is not valid for {1}."
    • The string value for "PropertyValueRequired" is used when the user did not enter any data for a field which is not nullable (for example, an integer field). The default message for this is: "A value is required."

    It's important to note in the second case that, if you have the DataAnnotationsModelValidatorProvider in your validator providers list (which it is by default), then you will never see this second message. This provider sees non-optional fields and adds an implied [Required] attribute to them so that their messages will be consistent with other fields with explicit [Required] attributes and to ensure that you get client-side validation for required fields.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 6:20 PM
  • User1958445578 posted

    Diego,

    I can confirm that this is working in ASP.NET MVC 2. You *have* to use GlobalResources though -- it does not work with custom resource files, since the DefaultModelBinder uses HttpContext.GetGlobalResourceObject to obtain ResourceManager (which looks into App_GlobalResources to find the resources...)

    Miha

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, April 28, 2010 7:37 AM
  • User-1032240251 posted

    That message is part of MVC and provided by the ClientDataTypeModelValidatorProvider. Aside from the standard localization of MVC, this message isn't easily changeable (it was added at the last minute, and we didn't offer an override unfortunately). You can remove this behavior entirely (data type client-side validation) by removing that validator provider; you could also write your own, which returned "number" client-side validation rules with whatever message you wanted. The easiest way to do that would be to start with the source for ClientDataTypeModelValidatorProvider and making whatever modifications you feel necessary.

    Note that this validator provider is a client-side only validator provider, intended to verify that you only enter digits (and commas/decimal points) for values which are inherently numeric, like int, double, or decimal. Server side validation occurs during model binding automatically when the system attempts to convert your value into the correct type.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 29, 2010 6:13 PM

All replies

  • User1911587250 posted

    which validation method do you use ? DataAnnotations ? Client Side ? Server side ? could you post your code?


    Friday, January 8, 2010 3:15 PM
  • User150963435 posted

    Hi !

    I'm using an MVC project like that :

    - Web MVC2 project : Presentation layer

    - BLL Project : Services project with validation logic (I transmit the modelstate to the service layer and update it when i encouter business logic errors)

    - DAL Project : Data Layer using Nhibernate

    - DTO project : my business POCO


    The method I use : 

    I create strongly typed forms. Actions has strongly typed parameters and call Business Layer Services.

    The validation is done within Service Layer : When I call Insert or Update method, I call a validate function that updates modelstate (via a modelstatewrapper). Si it's quite normal usage (i think).


    But I think the problem isn't on which method i use because when I call the action, modelstate is already set with an error from MVC framework which is english string.

    So if I add a break point just onto the action definition I can see the validation error.

    I hope it will help you, but if you want code, which one do you want to see ?


    Thanks ;)

    Friday, January 8, 2010 6:12 PM
  • User-434868552 posted

    @ insomniak54

    if you are using the simple validation that is part of ASP.NET MVC 1.0, just specify the message in the language of your choice.

    e.g.:

    // POST: /Product/Create

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude="Id")] Product productToCreate)
    {
    // Validation logic
    if (productToCreate.UnitsInStock < 0)
    ModelState.AddModelError("UnitsInStock", "Units im Lager kann nicht weniger als Null.");
      if (productToCreate.UnitsInStock < 0)
    ModelState.AddModelError("UnitsInStock", "Unités en stock ne peut pas être inférieur à zéro.");
    if (productToCreate.UnitsInStock < 0)
    ModelState.AddModelError("UnitsInStock", "Units in stock cannot be less than zero.");


    Whatever method you are using, if you search in Visual Studio,
    you should be able to locate the string(s) that you wish to change.
    Just translate it (them) into the language of your choice.

    Some languages such as right to left languages and Asian languages
    may create special problems. For most left to right languages that
    use the roman alphabet you should have have very little difficulty
    if any at all because it appears you intend to support only a single
    language. Multi-lingual sites are slightly more difficult.
    Show romanization

    Regards,
    Gerry (Lowry)

    Friday, January 8, 2010 7:14 PM
  • User150963435 posted

    Hi Gerry

    Your example is exactly the good one to show what is annoying for me.

    Just imagine you have a Creation Date field into your create product form. product also have a creationdate property (DateTime)

    If the user fill in this field with something wrong - like "baddate" - instead of a correct formated date, you can't handle the date try parse because the creationdate property won't be set. My problem is that I can't handle this by testing if creationdate equals to datetime.Minvalue because if it's the case, my business rules set it to datetime.now.

    If you place a breakpoint just on public actionresult Create, then try to add a product with a bad formated date, try to see into modelstate.errors, you will see that there is already an error in english. I would like to handle this in place of framework, or just change it.


    Any idea ?

    Thanks


    Edit : I found a temporary solution : I use a modelstatewrapper into my service layer. When I use a controller, in its new, I instanciate the Service I have to use passing the modelstatewrapper into its parameters. So, into my validate function into my service, I just have to check if my modelstatewrapper has an error for CreationDate. If so, I delete it and replace it with my message. What do you think about that ?

    Saturday, January 9, 2010 5:43 AM
  • User-1032240251 posted

    This is a strong hint that you should use view models for binding between controller and view, and not your business objects.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 12:13 PM
  • User150963435 posted

    Ok but I think this is not a solution about validation messages from Framework.

    I had the same problem with WPF and validation messages. Whatever the method you use (IDataErrorInfo, Validation into Service Layer, DataAnnotations...) the default message sent by the framework (WPF or ASP.net MVC) will be there. It's an exception thrown during the validation of the form when it tries to fill the DateTime property (or every type you want) with a bad value (like text or something else, but not in the good format). The framework, catching the exception, will automatically generate a validation message telling that the value isn't in good format.

    With WPF, I found a solution using Validation with raw values before the framework tries to fill the property so I can handle it myself and return a message of my own in the good language.

    To make long story short : Try to create a new MVC projet, add a simple class with a datetime property, add a Create action and its view (strongly typed to your class).

    Now test the creation of a new object trough the form. If you type a wrong formatted date, you will see a validation message : "wrong value for blabla". Now place a breakpoint on the Create action open bracket ("{") and retry to type a wrong date. When you reach to the breakpoint, add a watch to this.modelstate and try to see if there is an error on your property name, you will see that there is an error.

    So my question is : with my little example, you have seen that a default english message is stored into the modelstate errors BEFORE you can do anything. So if it's before anything, why a view model, a service layer or whatever you want could handle this error and manage the message before the framework do ? (if you have a concrete example, I would be glad to see it because I really really have no idea about how to handle it)


    Thanks for your reply.

    BR

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 12:30 PM
  • User-1032240251 posted

    Ah, what you're talking about here isn't validation, but model binding failures. You can use resources for this message.

    Create a global resource class in App_GlobalResources, and set DefaultModelBinder.ResourceClassKey to the name of this class (for example, if you made "Messages.resx", then set ResourceClassKey to "Messages").

    There are two strings you can override in MVC 2:

    • The string value for "PropertyValueInvalid" is used when the data the user entered isn't compatible with the data type (for example, typing in "abc" for an integer field). The default message for this is: "The value '{0}' is not valid for {1}."
    • The string value for "PropertyValueRequired" is used when the user did not enter any data for a field which is not nullable (for example, an integer field). The default message for this is: "A value is required."

    It's important to note in the second case that, if you have the DataAnnotationsModelValidatorProvider in your validator providers list (which it is by default), then you will never see this second message. This provider sees non-optional fields and adds an implied [Required] attribute to them so that their messages will be consistent with other fields with explicit [Required] attributes and to ensure that you get client-side validation for required fields.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, January 9, 2010 6:20 PM
  • User150963435 posted

    Hi Brad,


    Thanks for your reply, it's exactly what I was looking for ! Many many thanks ;)

    Sunday, January 10, 2010 6:31 AM
  • User-885877314 posted

    Create a global resource class in App_GlobalResources, and set DefaultModelBinder.ResourceClassKey to the name of this class (for example, if you made "Messages.resx", then set ResourceClassKey to "Messages").

    There are two strings you can override in MVC 2:

    • The string value for "PropertyValueInvalid" is used when the data the user entered isn't compatible with the data type (for example, typing in "abc" for an integer field). The default message for this is: "The value '{0}' is not valid for {1}.

    I did this, but it is not working. I am using MVC 2 RTM.

    An interesting point is that the default message is "The field {0} must be a {1}." different from the one above.

    Is there any other strings that I should override?

    Thanks

    Wednesday, April 21, 2010 2:43 AM
  • User1958445578 posted

    Diego,

    I can confirm that this is working in ASP.NET MVC 2. You *have* to use GlobalResources though -- it does not work with custom resource files, since the DefaultModelBinder uses HttpContext.GetGlobalResourceObject to obtain ResourceManager (which looks into App_GlobalResources to find the resources...)

    Miha

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, April 28, 2010 7:37 AM
  • User-885877314 posted

    Hi Miha.

    If I run this method HttpContext.GetGlobalResourceObject("OverridedMessages", "PropertyValueInvalid") The return is "O valor '{0}' não é válido para {1}." PT culture or "The value '{0}' is not valid for {1}." En culture.

    So i guess i am configuring this rigth.

    My problem is that the default message when I input letters to a number field is "The field XYZ must be a number." wich is different from the "The value '{0}' is not valid for {1}."

    I ended up doing a custom validation attribute to assure that the field is a number (positive number, in my case) and now the error messages that it displays is my custom validation message.

    Thursday, April 29, 2010 2:18 PM
  • User-1032240251 posted

    That message is part of MVC and provided by the ClientDataTypeModelValidatorProvider. Aside from the standard localization of MVC, this message isn't easily changeable (it was added at the last minute, and we didn't offer an override unfortunately). You can remove this behavior entirely (data type client-side validation) by removing that validator provider; you could also write your own, which returned "number" client-side validation rules with whatever message you wanted. The easiest way to do that would be to start with the source for ClientDataTypeModelValidatorProvider and making whatever modifications you feel necessary.

    Note that this validator provider is a client-side only validator provider, intended to verify that you only enter digits (and commas/decimal points) for values which are inherently numeric, like int, double, or decimal. Server side validation occurs during model binding automatically when the system attempts to convert your value into the correct type.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, April 29, 2010 6:13 PM
  • User2024153942 posted

    One year later :)  Has there been any progress on this?  in MVC3 space?  I'm running into a similar problem where I want to change the default error messages and sync them up so atleast server and client validation show the same error message.  Both are generated on the server so I don't see why not.  The [Required] attribute does it right.

     

    Tuesday, April 26, 2011 8:41 PM
  • User-2044164327 posted

    That message is part of MVC and provided by the ClientDataTypeModelValidatorProvider. Aside from the standard localization of MVC, this message isn't easily changeable (it was added at the last minute, and we didn't offer an override unfortunately).

    This is a real pain if you're in a non english culture. I would vote for a better support for localization in ASP.Net MVC 4. Ideally the framework should provide localized messages according to the thread culture. If not, at least there should be a centralized place where we could override ALL client and server validation messages with our own.

     

    Monday, May 23, 2011 8:54 PM