问题
How can I use resources from a different assembly to override the default attribute error messages in my MVC5 application?
My website is namespaced: Company.Web
My resources assembly is namespaced: Company.Web.Resources
I can easily localize attribute error messages individually using:
[Required(ErrorMessageResourceName = "PropertyValueRequired", ErrorMessageResourceType = typeof(Company.Web.Resources.Messages))]
However, since our error message is always "Required", I'd simply like to put the [Required] attribute without having to specify the resource name. I'd also like to override the default data type messages output by MVC which you can't do via an attribute.
The field {0} must be a date.
I'd like to be
Invalid date
I've seen examples where you can put the resource files in App_GlobalResources (with keys PropertyValueRequired, FieldMustBeDate, FieldMustBeNumeric) and setting ClientDataTypeModelValidatorProvider.ResourceClassKey, but I already have an external resources assembly I want to use.
I've tried using the following in my Global.asax with no luck:
ClientDataTypeModelValidatorProvider.ResourceClassKey = "Company.Web.Resources.Messages"
How can I accomplish this? Any ideas?
UPDATE (Partial Resolution)
I can solve my attribute-based problem simply by creating new validation adapters and using them in lieu of the default:
public class MyRequiredAttributeAdapter : RequiredAttributeAdapter
{
public MyRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
: base(metadata, context, attribute)
{
if (attribute.ErrorMessage.IsNullOrWhitespace()
&& attribute.ErrorMessageResourceName.IsNullOrWhitespace()
&& attribute.ErrorMessageResourceType == null)
{
attribute.ErrorMessageResourceType = typeof (Resources.Validation.Messages);
attribute.ErrorMessageResourceName = "PropertyValueRequired";
}
}
}
Global.asax
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(MyRequiredAttributeAdapter));
However, this still leaves me scratching my head on how to override the default data type message for non-null properties such as DateTime and int. Also, I believe there are some I am unable to override because they are internal (DataTypeAttributeAdapter, CompareAttributeAdapter).
回答1:
This might be quite late, but then here is a solution that should work based primarily on the logic behind your partial solution.
Implement a custom
RequiredAttributefor your projectpublic class MyRequiredAttribute : RequiredAttribute { //Your custom code }Modify your
MyRequiredAttributeAdaptercode as shown. Notice that you now need to inherit from the genericDataAnnotationsModelValidatorclass, which allows you pass in your customMyRequiredAttributepublic class MyRequiredAttributeAdapter : DataAnnotationsModelValidator<MyRequiredAttribute> { public MyRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, MyRequiredAttribute attribute) : base(metadata, context, attribute) { if (string.IsNullOrWhiteSpace(attribute.ErrorMessage) && string.IsNullOrWhiteSpace(attribute.ErrorMessageResourceName) && attribute.ErrorMessageResourceType == null) { attribute.ErrorMessageResourceType = typeof(Resources.Validation.Messages); attribute.ErrorMessageResourceName = "PropertyValueRequired"; } } }Add this to Global.asax (modified from what you have in your partial solution)
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(MyRequiredAttribute), typeof(MyRequiredAttributeAdapter));
回答2:
To override the default data type message for non-null properties such as DateTime and int,
implement an own MyClientDataTypeModelValidatorProvider based on the MVC ClientDataTypeModelValidatorProvider.
Add that instance to ModelValidatorProviders.Providers, and removed the default one.
So, put this into Global.asax:
var clientDataTypeModelValidatorProviderIndex = ModelValidatorProviders.Providers.FindIndex(modelValidatorProvider => modelValidatorProvider is ClientDataTypeModelValidatorProvider);
ModelValidatorProviders.Providers.RemoveAt(clientDataTypeModelValidatorProviderIndex);
ModelValidatorProviders.Providers.Add(new MyClientDataTypeModelValidatorProvider());
Tested with MVC 5
来源:https://stackoverflow.com/questions/25084212/globally-override-asp-net-mvc-default-attribute-error-messages