C# 全局覆盖ASP.Net MVC默认属性错误消息

C# 全局覆盖ASP.Net MVC默认属性错误消息,c#,asp.net,asp.net-mvc,unobtrusive-validation,C#,Asp.net,Asp.net Mvc,Unobtrusive Validation,如何使用来自不同程序集的资源覆盖MVC5应用程序中的默认属性错误消息 我的网站名为Company.Web 我的资源程序集的名称空间为:Company.Web.resources 我可以使用以下方法轻松地分别本地化属性错误消息: [Required(ErrorMessageResourceName = "PropertyValueRequired", ErrorMessageResourceType = typeof(Company.Web.Resources.Messages))] 但是,由于

如何使用来自不同程序集的资源覆盖MVC5应用程序中的默认属性错误消息

我的网站名为Company.Web

我的资源程序集的名称空间为:Company.Web.resources

我可以使用以下方法轻松地分别本地化属性错误消息:

[Required(ErrorMessageResourceName = "PropertyValueRequired", ErrorMessageResourceType = typeof(Company.Web.Resources.Messages))]
但是,由于我们的错误消息总是“Required”,我只想添加
[Required]
属性,而不必指定资源名称。我还想覆盖MVC输出的默认数据类型消息,这是通过属性无法做到的

字段{0}必须是日期

我想去

无效日期

我看到过一些示例,其中您可以将资源文件放入App_GlobalResources(带有键
PropertyValueRequired
FieldMustBeDate
FieldMustBeNumeric
)和设置
clientdatatypemodelvalidateprovider.ResourceClassKey
,但我已经有了一个想要使用的外部资源程序集

我在我的Global.asax中尝试过使用以下内容,但没有成功:

ClientDataTypeModelValidatorProvider.ResourceClassKey = "Company.Web.Resources.Messages"
我怎样才能做到这一点?有什么想法吗

更新(部分分辨率)

我可以通过创建新的验证适配器并使用它们代替默认适配器来解决基于属性的问题:

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));

但是,这仍然让我对如何为非空属性(如DateTime和int)重写默认数据类型消息感到困惑。此外,我认为有些消息是内部的(DataTypeAttributeAdapter,CompareAttributeAdapter),因此无法重写。

这可能已经太晚了,但是这里有一个解决方案,它应该主要基于部分解决方案背后的逻辑

  • 为项目实现自定义
    RequiredAttribute

    public class MyRequiredAttribute : RequiredAttribute
    {
        //Your custom code
    }
    
  • 如图所示修改您的
    MyRequiredAttributeAdapter
    代码。请注意,现在需要从generic
    DataAnnotationsModelValidator
    类继承,该类允许您传入自定义的
    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";
            }
        }
    }
    

  • 要覆盖非空属性(如DateTime和int)的默认数据类型消息,
    基于MVC实现自己的
    MyClientDataTypeModelValidatorProvider

    将该实例添加到
    modelvalidateproviders.Providers
    ,并删除默认实例

    因此,将其放入Global.asax:

    var clientDataTypeModelValidatorProviderIndex = ModelValidatorProviders.Providers.FindIndex(modelValidatorProvider => modelValidatorProvider is ClientDataTypeModelValidatorProvider);
    ModelValidatorProviders.Providers.RemoveAt(clientDataTypeModelValidatorProviderIndex);
    ModelValidatorProviders.Providers.Add(new MyClientDataTypeModelValidatorProvider());
    

    使用MVC 5测试

    是,后期打印错误已修复。谢谢。难道你不能继承内置属性创建自己的属性吗?是的,很遗憾,这不能处理日期和数字的内置数据类型验证。例如,当模型上有一个不可为null的DateTime属性(根本不使用任何属性)时,消息输出为“字段{0}必须是日期”。我想说“无效日期”。可能是重复的而不是重复的。所有这些解决方案都依赖于使用App_GlobalResources在同一web程序集中创建的资源。我的资源字符串需要从另一个程序集派生。
    var clientDataTypeModelValidatorProviderIndex = ModelValidatorProviders.Providers.FindIndex(modelValidatorProvider => modelValidatorProvider is ClientDataTypeModelValidatorProvider);
    ModelValidatorProviders.Providers.RemoveAt(clientDataTypeModelValidatorProviderIndex);
    ModelValidatorProviders.Providers.Add(new MyClientDataTypeModelValidatorProvider());