Globally Override ASP.Net MVC Default Attribute Error Messages

帅比萌擦擦* 提交于 2019-12-10 07:41:47

问题


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.

  1. Implement a custom RequiredAttribute for your project

    public class MyRequiredAttribute : RequiredAttribute
    {
        //Your custom code
    }
    
  2. Modify your MyRequiredAttributeAdapter code as shown. Notice that you now need to inherit from the generic DataAnnotationsModelValidator class, which allows you pass in your custom MyRequiredAttribute

    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";
            }
        }
    }
    
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!