I have my resource files in separate assembly MyApp.Resources.dll. I can use the resources without any problem but the issue appears when I want to change (localize) the def
I have found solution for this case (when resources are in separate assembly).
To get it working you should create custom ResourceProviderFactory and register it as default ResourceProviderFactoryType in web.config section.
Setup Localization
// Modify web.config in run-time and setup custom ResourceProviderFactory
var globalization = WebConfigurationManager.GetSection("system.web/globalization") as GlobalizationSection;
var readonlyField = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
readonlyField.SetValue(globalization, false);
globalization.ResourceProviderFactoryType = typeof(ValidationResourceProviderFactory).FullName;
var resourcesClass = typeof(ValidationResources).FullName;
DefaultModelBinder.ResourceClassKey = resourcesClass;
ValidationExtensions.ResourceClassKey = resourcesClass;
ValidationResourceProviderFactory
public sealed class ValidationResourceProviderFactory: System.Web.Compilation.ResourceProviderFactory
{
public ValidationResourceProviderFactory()
{
}
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
return new GlobalResourceProvider(classKey);
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
throw new NotImplementedException("Local resources are not supported yet");
}
}
GlobalResourceProvider
public class GlobalResourceProvider : IResourceProvider
{
public GlobalResourceProvider(string classKey)
{
Throw.IfBadArgument(() => String.IsNullOrEmpty(classKey), "classKey");
var type = Type.GetType(classKey, false);
if (type == null)
{
var asmName = classKey;
var className = classKey;
while(asmName.IndexOf(".") > -1 && type == null)
{
asmName = asmName.Substring (0, asmName.LastIndexOf("."));
className = classKey.Substring(asmName.Length + 1);
type = Type.GetType(classKey + "," + asmName, false);
}
}
Throw.IfNullArgument(type, "type");
Manager = CreateResourceManager(classKey, type.Assembly);
}
public ResourceManager Manager { get; set; }
#region IResourceProvider implementation
public IResourceReader ResourceReader { get; set; }
public object GetObject(string resourceKey, CultureInfo culture)
{
return Manager.GetObject(resourceKey, culture);
}
#endregion
private ResourceManager CreateResourceManager(string classKey, Assembly assembly)
{
return new ResourceManager(classKey, assembly);
}
}
UPD
RESX for ValidationResources
Just add new resources class as ValidationResources and place provided XML there
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Please enter a value with a valid mimetype.
Please enter a valid credit card number.
Please enter a valid date.
Please enter a valid date (ISO).
Please enter a valid date and time.
Please enter only digits.
Please enter a valid email address.
Please enter the same value again.
Please enter a valid date for "{0}".
Localization for legacy MVC ClientDataTypeModelValidatorProvider
Please enter a valid number for "{0}".
Localization for legacy MVC ClientDataTypeModelValidatorProvider
Invalid property value: {0}
Please enter a value less than or equal to {0}.
Please enter no more than {0} characters.
Please enter a value greater than or equal to {0}.
Please enter at least {0} characters.
Please enter a valid number.
The value "{0}" is invalid for the property "{1}"
Localization for legacy MVC DefaultModelBinder
The "{0}" field is required.
Localization for legacy MVC DefaultModelBinder
Please enter a value between {1} and {2}.
Please enter a value between {0} and {1}.
Please enter a value between {0} and {1} characters long.
Please fix this field.
Please enter an integer value, sign allowed.
Please enter a valid time.
Please enter a positive integer value.
Please enter a valid URL.
<null>