问题
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
RequiredAttribute
for your projectpublic class MyRequiredAttribute : RequiredAttribute { //Your custom code }
Modify your
MyRequiredAttributeAdapter
code as shown. Notice that you now need to inherit from the genericDataAnnotationsModelValidator
class, which allows you pass in your customMyRequiredAttribute
public 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