0

I have a ViewModel property:

public decimal decProperty { get; set; }

I have found it difficult to customise the Error message for the above. However if I code the following, I can specify the error message.

[RegularExpression(@"\d+(\.\d{1,2})?", ErrorMessage = "Invalid decimal")]
public string strProperty { get; set; }

Ideally I just want to keep the type as "decimal?". How could I just specify "Invalid decimal" in this case?

Thanks.

SamJolly
  • 6,347
  • 13
  • 59
  • 125
  • Is it the same question http://stackoverflow.com/q/6587816/5311735? – Evk Mar 20 '17 at 13:36
  • Are you just wanting to change the actual error message that is displayed when you enter an invalid value? –  Mar 20 '17 at 21:07
  • @StephenMuecke, Yes I wanted to just change the default message which is displayed when .NET does it default type validation. Thanks. – SamJolly Mar 21 '17 at 12:49
  • Refer [this answer](http://stackoverflow.com/questions/6214066/how-to-change-default-validation-error-message-in-asp-net-mvc) –  Mar 21 '17 at 12:51
  • @StephenMueke, Thanks but the problem with this is that it changes the messages globally and I want to just define custom messages for class scope or property scope. – SamJolly Mar 21 '17 at 15:38

1 Answers1

2

You could use the Range attribute as a workaround. According to this answer, the range will only be tested if a value exists.

[Range(decimal.MinValue, decimal.MaxValue, ErrorMessage = "Invalid decimal")]
public decimal? decProperty { get; set; }

By the way, you can also define resources so your error messages become translatable.

[Range(decimal.MinValue, decimal.MaxValue, ErrorMessageResourceType = typeof(Resources), 
    ErrorMessageResourceName = "Decimal_ValidationError")]

EDIT

As it turns out, Range only works for int and double.

Another way is to implement a custom ClientDataTypeModelValidatorProvider and ModelValidator. This gives you full control. They are registered in the Global.asax Application_Start(). This will work every time the ModelBinder tries to bind a decimal, no need to attribute every ViewModel. Unfortunately, I can't show you our implementation, because it is owned by the company. Use ILSpy to take a look at the code from MS.

http://jwwishart.blogspot.co.at/2011/03/custom-server-and-client-side-required.html

Community
  • 1
  • 1
Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36
  • Thanks, this looks promising. Is it possible to set these annotations at class level? – SamJolly Mar 21 '17 at 15:41
  • The `Range` attribute only works on properties, fields or parameters. I fear the same is true for most other Attributes from `System.ComponentModel.DataAnnotations`. Take a look at the `AttributeUsage` in the implementation of these attributes. – Georg Patscheider Mar 21 '17 at 15:44
  • 1
    Range only supports "int" and "double". I am trying "double". – SamJolly Mar 21 '17 at 15:56
  • Oops I overlooked that. Note that `decimal` provides 8-29 significant digits, `double` only 15-16 digits, so I am not sure if this will work for you :( – Georg Patscheider Mar 21 '17 at 16:03
  • No I am not sure... I think using regex is the best option so far. It is the most controllable as per my question example] – SamJolly Mar 21 '17 at 16:15
  • Take a look at `ClientDataTypeModelValidatorProvider `, this might be more suited to your requirement anyways. – Georg Patscheider Mar 21 '17 at 16:34