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.



No Comments