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,
1 |
ClientDataTypeModelValidatorProvider.ResourceClassKey
= "MyResources";
|
2 |
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,
1 |
FieldMustBeDate The field {0} must be a
date.
|
2 |
FieldMustBeNumeric The field {0} must be a
number.
|
3 |
PropertyValueInvalid The value '{0}' is not
valid for {1}.
|
4 |
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),
01 |
public
class
MyErrorMessageProvider
|
02 |
{
|
03 |
private
static
string
_resourceClassKey;
|
04 |
05 |
public
static
void
SetResourceClassKey(string
resourceClassKey){
|
06 |
if(resourceClassKey == null){
|
07 |
throw
new
ArgumentNullException("resourceClassKey");
|
08 |
}
|
09 |
_resourceClassKey = resourceClassKey;
|
10 |
ModelBinderErrorMessageProviders.ValueRequiredErrorMessageProvider
=
MyErrorMessageProvider.DefaultValueRequiredErrorMessageProvider;
|
11 |
ModelBinderErrorMessageProviders.TypeConversionErrorMessageProvider
=
MyErrorMessageProvider.DefaultTypeConversionErrorMessageProvider;
|
12 |
}
|
13 |
14 |
private
static
string
DefaultTypeConversionErrorMessageProvider(ModelBindingExecutionContext
modelBindingExecutionContext, ModelMetadata
modelMetadata, object
incomingValue)
|
15 |
{
|
16 |
return
GetResourceCommon(modelBindingExecutionContext,
modelMetadata, incomingValue, new
Func<ModelBindingExecutionContext, string>(GetValueInvalidResource));
|
17 |
}
|
18 |
19 |
private
static
string
DefaultValueRequiredErrorMessageProvider(ModelBindingExecutionContext
modelBindingExecutionContext, ModelMetadata
modelMetadata, object
incomingValue)
|
20 |
{
|
21 |
return
GetResourceCommon(modelBindingExecutionContext,
modelMetadata, incomingValue, new
Func<ModelBindingExecutionContext, string>(GetValueRequiredResource));
|
22 |
}
|
23 |
24 |
private
static
string
GetResourceCommon(ModelBindingExecutionContext
modelBindingExecutionContext, ModelMetadata
modelMetadata, object
incomingValue,
Func<ModelBindingExecutionContext, string> resourceAccessor)
|
25 |
{
|
26 |
string
displayName =
modelMetadata.GetDisplayName();
|
27 |
string
str =
resourceAccessor(modelBindingExecutionContext);
|
28 |
object[] objArray = new
object[2];
|
29 |
objArray[0] = incomingValue;
|
30 |
objArray[1] = displayName;
|
31 |
string
str1 = string.Format(CultureInfo.CurrentCulture, str,
objArray);
|
32 |
return
str1;
|
33 |
}
|
34 |
35 |
private
static
string
GetUserResourceString(ModelBindingExecutionContext
modelBindingExecutionContext, string
resourceName, string
resourceClassKey)
|
36 |
{
|
37 |
if
(string.IsNullOrEmpty(resourceClassKey) ||
modelBindingExecutionContext == null
|| modelBindingExecutionContext.HttpContext
== null)
|
38 |
{
|
39 |
return
null;
|
40 |
}
|
41 |
else
|
42 |
{
|
43 |
return
modelBindingExecutionContext.HttpContext.GetGlobalResourceObject(resourceClassKey,
resourceName, CultureInfo.CurrentUICulture) as
string;
|
44 |
}
|
45 |
}
|
46 |
47 |
private
static
string
GetUserResourceString(ModelBindingExecutionContext
modelBindingExecutionContext, string
resourceName)
|
48 |
{
|
49 |
return
GetUserResourceString(modelBindingExecutionContext,
resourceName, _resourceClassKey);
|
50 |
}
|
51 |
52 |
private
static
string
GetValueInvalidResource(ModelBindingExecutionContext
modelBindingExecutionContext)
|
53 |
{
|
54 |
string
userResourceString =
GetUserResourceString(modelBindingExecutionContext, "PropertyValueInvalid");
|
55 |
return
userResourceString;
|
56 |
}
|
57 |
58 |
private
static
string
GetValueRequiredResource(ModelBindingExecutionContext
modelBindingExecutionContext)
|
59 |
{
|
60 |
string
userResourceString =
GetUserResourceString(modelBindingExecutionContext, "PropertyValueRequired");
|
61 |
return
userResourceString;
|
62 |
}
|
63 |
}
|
and then we can set our resource class file at Global.asax Application_Start method,
1 |
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.