Localizing Default Error Messages in ASP.NET MVC and WebForm
Introduction:
System.ComponentModel.DataAnnotations validation attributes (like RequiredAttribute) allows us to localize error messages using ErrorMessageResourceName and ErrorMessageResourceType. But some error messages cannot be localized using these properties. For example, 'The value X is not valid for Y'. In this article, I will quickly show you how to localize these error messages in ASP.NET MVC and ASP.NET WebForm.
Description:
For localizing default error messages in ASP.NET MVC we will set these below properties in Global.asax Application_Start method,
ClientDataTypeModelValidatorProvider.ResourceClassKey = "MyResources"; DefaultModelBinder.ResourceClassKey = "MyResources";
Next, create a MyResources.resx resource file and/or your culture specific resource file MyResources.xx.resx inside App_GlobalResources folder where we can override FieldMustBeDate, FieldMustBeNumeric, PropertyValueInvalid and PropertyValueRequired messages. Here are the default values,
FieldMustBeDate The field {0} must be a date. FieldMustBeNumeric The field {0} must be a number. PropertyValueInvalid The value '{0}' is not valid for {1}. PropertyValueRequired A value is required.
For WebForm, we need to localize PropertyValueInvalid and PropertyValueRequired. But here we need to do some more work. Just add a class MyErrorMessageProvider.cs which do all the work for us(Note: most code are copied from System.Web.dll),
public class MyErrorMessageProvider { private static string _resourceClassKey; public static void SetResourceClassKey(string resourceClassKey){ if(resourceClassKey == null){ throw new ArgumentNullException("resourceClassKey"); } _resourceClassKey = resourceClassKey; ModelBinderErrorMessageProviders.ValueRequiredErrorMessageProvider = MyErrorMessageProvider.DefaultValueRequiredErrorMessageProvider; ModelBinderErrorMessageProviders.TypeConversionErrorMessageProvider = MyErrorMessageProvider.DefaultTypeConversionErrorMessageProvider; } private static string DefaultTypeConversionErrorMessageProvider(ModelBindingExecutionContext modelBindingExecutionContext, ModelMetadata modelMetadata, object incomingValue) { return GetResourceCommon(modelBindingExecutionContext, modelMetadata, incomingValue, new Func<ModelBindingExecutionContext, string>(GetValueInvalidResource)); } private static string DefaultValueRequiredErrorMessageProvider(ModelBindingExecutionContext modelBindingExecutionContext, ModelMetadata modelMetadata, object incomingValue) { return GetResourceCommon(modelBindingExecutionContext, modelMetadata, incomingValue, new Func<ModelBindingExecutionContext, string>(GetValueRequiredResource)); } private static string GetResourceCommon(ModelBindingExecutionContext modelBindingExecutionContext, ModelMetadata modelMetadata, object incomingValue, Func<ModelBindingExecutionContext, string> resourceAccessor) { string displayName = modelMetadata.GetDisplayName(); string str = resourceAccessor(modelBindingExecutionContext); object[] objArray = new object[2]; objArray[0] = incomingValue; objArray[1] = displayName; string str1 = string.Format(CultureInfo.CurrentCulture, str, objArray); return str1; } private static string GetUserResourceString(ModelBindingExecutionContext modelBindingExecutionContext, string resourceName, string resourceClassKey) { if (string.IsNullOrEmpty(resourceClassKey) || modelBindingExecutionContext == null || modelBindingExecutionContext.HttpContext == null) { return null; } else { return modelBindingExecutionContext.HttpContext.GetGlobalResourceObject(resourceClassKey, resourceName, CultureInfo.CurrentUICulture) as string; } } private static string GetUserResourceString(ModelBindingExecutionContext modelBindingExecutionContext, string resourceName) { return GetUserResourceString(modelBindingExecutionContext, resourceName, _resourceClassKey); } private static string GetValueInvalidResource(ModelBindingExecutionContext modelBindingExecutionContext) { string userResourceString = GetUserResourceString(modelBindingExecutionContext, "PropertyValueInvalid"); return userResourceString; } private static string GetValueRequiredResource(ModelBindingExecutionContext modelBindingExecutionContext) { string userResourceString = GetUserResourceString(modelBindingExecutionContext, "PropertyValueRequired"); return userResourceString; } }
and then we can set our resource class file at Global.asax Application_Start method,
MyErrorMessageProvider.SetResourceClassKey("MyResources");
Summary:
In this article, I showed you how easily we can localize error messages in ASP.NET MVC and ASP.NET WebForm . Hopefully you will enjoy my this article too.