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".
You can provide a custom error message either in the data annotation attribute or in the ValidationMessageFor() method.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With