Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC - Custom validation message for value types

Tags:

When I use UpdateModel or TryUpdateModel, the MVC framework is smart enough to know if you are trying to pass in a null into a value type (e.g. the user forgets to fill out the required Birth Day field) .

Unfortunately, I don't know how to override the default message, "A value is required." in the summary into something more meaningful ("Please enter in your Birth Day").

There has to be a way of doing this (without writing too much work-around code), but I can't find it. Any help?

EDIT

Also, I guess this would also be an issue for invalid conversions, e.g. BirthDay = "Hello".

like image 545
Giovanni Galbo Avatar asked Mar 14 '09 17:03

Giovanni Galbo


People also ask

Which property of validation attribute is used for displaying the custom error message?

You can provide a custom error message either in the data annotation attribute or in the ValidationMessageFor() method.


1 Answers

Make your own ModelBinder by extending DefaultModelBinder:

public class LocalizationModelBinder : DefaultModelBinder 

Override SetProperty:

        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);          foreach (var error in bindingContext.ModelState[propertyDescriptor.Name].Errors.             Where(e => IsFormatException(e.Exception)))         {             if (propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)] != null)             {                 string errorMessage =                     ((TypeErrorMessageAttribute)propertyDescriptor.Attributes[typeof(TypeErrorMessageAttribute)]).GetErrorMessage();                 bindingContext.ModelState[propertyDescriptor.Name].Errors.Remove(error);                 bindingContext.ModelState[propertyDescriptor.Name].Errors.Add(errorMessage);                 break;             }         } 

Add the function bool IsFormatException(Exception e) to check if an Exception is a FormatException:

if (e == null)             return false;         else if (e is FormatException)             return true;         else             return IsFormatException(e.InnerException); 

Create an Attribute class:

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] public class TypeErrorMessageAttribute : Attribute {     public string ErrorMessage { get; set; }     public string ErrorMessageResourceName { get; set; }     public Type ErrorMessageResourceType { get; set; }      public TypeErrorMessageAttribute()     {     }      public string GetErrorMessage()     {         PropertyInfo prop = ErrorMessageResourceType.GetProperty(ErrorMessageResourceName);         return prop.GetValue(null, null).ToString();     } } 

Add the attribute to the property you wish to validate:

[TypeErrorMessage(ErrorMessageResourceName = "IsGoodType", ErrorMessageResourceType = typeof(AddLang))]     public bool IsGood { get; set; } 

AddLang is a resx file and IsGoodType is the name of the resource.

And finally add this into Global.asax.cs Application_Start:

ModelBinders.Binders.DefaultBinder = new LocalizationModelBinder(); 

Cheers!

like image 69
Cristi Todoran Avatar answered Sep 28 '22 10:09

Cristi Todoran