Reputation: 409
I'm using entity framework code first in an ASP MVC project, and I'd like to change the error message that appears for validation of a numeric type.
I have a property like
public decimal Amount1 { get; set; }
If I enter a non-number in the field, I get the message: The field Amount1 must be a number.
How do I change that message?
For other validations, like Required
I can just use the ErrorMessage
parameter like: [Required(ErrorMessage = "My message...")]
Is there something similar for validating types?
Thank you.
Upvotes: 3
Views: 4597
Reputation: 14484
While it's not possible to change the whole message, you can at least change the string used to reference the field. Use the [Display(Name = "amount field"]
attribute, like:
[BindProperty]
[Display(Name = "line length")]
public decimal? LineLength { get; set; }
If the user enters a string into a field like this, they will at least see an error message that reads "The value 'sdf' is not valid for line length."
Not a complete solution, but good enough in many scenarios.
Upvotes: 0
Reputation: 6322
Unfortunately Microsoft didn't expose any interfaces to change the default messages.
But if you are desperate enough to change these non friendly messages, you can do so by creating validation attribute for decimal, creating corresponding validator and finally register it with DataAnnotationsModelValidatorProvider at the application startup. Hope this helps.
UPDATE:
Sample below
Step 1: Create validation attribute
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false)]
public class ValidDecimalAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
if (value == null || value.ToString().Length == 0) {
return ValidationResult.Success;
}
decimal d;
return !decimal.TryParse(value.ToString(), out d) ? new ValidationResult(ErrorMessage) : ValidationResult.Success;
}
}
Step 2: Create validator
public class ValidDecimalValidator : DataAnnotationsModelValidator<ValidDecimal>
{
public ValidDecimalValidator(ModelMetadata metadata, ControllerContext context, ValidDecimal attribute)
: base(metadata, context, attribute)
{
if (!attribute.IsValid(context.HttpContext.Request.Form[metadata.PropertyName]))
{
var propertyName = metadata.PropertyName;
context.Controller.ViewData.ModelState[propertyName].Errors.Clear();
context.Controller.ViewData.ModelState[propertyName].Errors.Add(attribute.ErrorMessage);
}
}
}
Step 3: Register the adapter in Global.asax under Application_Start() method or Main() method
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(ValidDecimal), typeof(ValidDecimalValidator));
Step 4: Finally decorate your property in your model with this attribute
[ValidDecimal(ErrorMessage = "Only decimal numbers allowed")]
public decimal CPEHours { get; set; }
Hope it helps.
Upvotes: 1
Reputation: 7019
I couldn't find a clean solution. If there is something like [Required]
you could override it in the same way. Only option I find is to remove and add another error into the model state. Again NOT the best option if you have better alternates, but does the job. This example only works if you have something like must be a number
at the end. You can create a filter with this kind of loop:
foreach (var m in ModelState)
{
var errors = m.Value.Errors;
foreach (var error in errors)
{
if (error.ErrorMessage.EndsWith("must be a number"))
{
errors.Remove(error);
ModelState.AddModelError(m.Key, $"This is my own validation");
}
}
}
Upvotes: 0