Asp.net mvc MVC:覆盖默认验证消息

Asp.net mvc MVC:覆盖默认验证消息,asp.net-mvc,data-annotations,html-helper,Asp.net Mvc,Data Annotations,Html Helper,在MVC的世界里,我有这个视图模型 public class MyViewModel{ [Required] public string FirstName{ get; set; } } …在我看来这类事情 <%= Html.ValidationSummary("Please correct the errors and try again.") %> <%= Html.TextBox("FirstName") %> <%= Html.Validation

在MVC的世界里,我有这个视图模型

public class MyViewModel{

[Required]
public string FirstName{ get; set; }    }
…在我看来这类事情

<%= Html.ValidationSummary("Please correct the errors and try again.") %>
<%= Html.TextBox("FirstName") %>
<%= Html.ValidationMessage("FirstName", "*") %>
..现在获取“需要名字字段”

到目前为止一切都很好

所以现在我希望错误消息显示“名字等等”。如何覆盖默认消息以显示DisplayName+“诸如此类”,而不使用以下内容注释所有属性

[Required(ErrorMessage = "First Name Blah Blah")]
干杯


Etfirfax

您可以编写自己的属性:

public class MyRequiredAttribute : ValidationAttribute
{
    MyRequiredAttribute() : base(() => "{0} blah blah blah blaaaaaah")
    {

    }

    public override bool IsValid(object value)
    {
        if (value == null)
        {
            return false;
        }
        string str = value as string;
        if (str != null)
        {
            return (str.Trim().Length != 0);
        }
        return true;
    }
}
这是来自Reflector的RequiredAttribute的副本,错误消息已更改。

只需更改即可

public class GenericRequired: RequiredAttribute
{
    public GenericRequired()
    {
        this.ErrorMessage = "{0} Blah blah"; 
    }
}
[Required] 


RequiredAttribute似乎没有实现IClientValidable,因此如果覆盖RequiredAttribute,它会中断客户端验证

所以这就是我所做的,它是有效的。希望这对别人有帮助

public class CustomRequiredAttribute : RequiredAttribute, IClientValidatable
{
    public CustomRequiredAttribute()
    {
        this.ErrorMessage = "whatever your error message is";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "required"
        };
    }
}
公共类CustomRequiredAttribute:RequiredAttribute,IClientValidable { 公共CustomRequiredAttribute() { this.ErrorMessage=“无论您的错误消息是什么”; } 公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文) { 返回新的ModelClientValidationRule { ErrorMessage=this.ErrorMessage, ValidationType=“必需” }; } }
这对我很有效。仔细阅读代码中的注释。(根据乍得的答复)

//保持名称与原始名称相同,它有助于触发原始javascript
//用于客户端验证的函数。
公共类RequiredAttribute:System.ComponentModel.DataAnnotations.RequiredAttribute,IClientValidatable
{
公共RequiredAttribute()
{
this.ErrorMessage=“Message”//不会再次被调用。只调用一次。
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
返回新的ModelClientValidationRule
{
ErrorMessage=“Message”,//每个请求都会调用它,因此它的内容可以是动态的。
ValidationType=“必需”
};
}
}
Edit:我之所以发布此消息,是因为我正在寻找具有[Required]属性的解决方案,但在找到它时遇到了问题。创建新的Q/A看起来不太好,因为这个问题已经存在。 我试图解决同样的问题,我在MVC4中找到了非常简单的解决方案

首先,您可能必须将错误消息存储在某个地方。我使用了自定义资源,详细描述见

重要的是,我可以通过调用ResourcesProject.Resources.SomeCustomError或ResourcesProject.Resources.MainPageTitle等获取任何资源(甚至错误消息)。每次我尝试访问Resources类时,它都会从当前线程获取区域性信息并返回正确的语言

我在ResourcesProject.Resources.RequiredAttribute中收到字段验证的错误消息。要将此消息设置为显示在视图中,只需使用这两个参数更新[Required]属性

ErrorMessageResourceType-将被调用的类型(在我们的示例ResourcesProject.Resources中)

ErrorMessageResourceName-属性,将对上述类型调用该属性(在我们的示例中为RequiredAttribute)

这里是一个非常简化的登录模型,它只显示用户名验证消息。当该字段为空时,它将从ResourcesProject.Resources.RequiredAttribute获取字符串,并将其显示为错误

    public class LoginModel
    {        
        [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName="RequiredAttribute")]
        [Display(Name = "User name")]
        public string UserName { get; set; }
}

下面是一种不用子类化
RequiredAttribute
的方法。只需创建一些属性适配器类。这里我使用的是
ErrorMessageResourceType
/
ErrorMessageResourceName
(带有资源),但您可以轻松设置
ErrorMessage
,甚至在设置这些覆盖之前检查覆盖是否存在

Global.asax.cs:

public class MvcApplication : HttpApplication {
    protected void Application_Start() {
        // other stuff here ...
        DataAnnotationsModelValidatorProvider.RegisterAdapter(
            typeof(RequiredAttribute), typeof(CustomRequiredAttributeAdapter));
        DataAnnotationsModelValidatorProvider.RegisterAdapter(
            typeof(StringLengthAttribute), typeof(CustomStringLengthAttributeAdapter));
    }
}

private class CustomRequiredAttributeAdapter : RequiredAttributeAdapter {
    public CustomRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
        : base(metadata, context, attribute)
    {
        attribute.ErrorMessageResourceType = typeof(Resources);
        attribute.ErrorMessageResourceName = "ValRequired";
    }
}

private class CustomStringLengthAttributeAdapter : StringLengthAttributeAdapter {
    public CustomStringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
        : base(metadata, context, attribute)
    {
        attribute.ErrorMessageResourceType = typeof(Resources);
        attribute.ErrorMessageResourceName = "ValStringLength";
    }
}

此示例要求您创建名为Resources.resx的资源文件,其中
ValRequired
作为新的必需默认消息,而
ValStringLength
作为字符串长度超过默认消息。请注意,对于这两种情况,
{0}
都会接收字段的名称,您可以使用
[Display(name=“field name”)]

设置该名称,这是一个非常好的解决方案,而且非常简单。谢谢但是,为什么在我重写缺省Required属性的行为时,会出现post,这样除了字段验证器之外还会出现登录表单错误消息;而当使用默认的required属性时,只显示字段验证程序消息?Chad的解决方案对我来说非常有用,它还可以从“无效用户或密码”中删除消息。它将以不引人注目的方式中断jQuery验证。为什么在我重写默认必需属性的行为时,似乎必须进行回发,以便在字段验证程序之外显示登录表单错误消息;而当使用默认的required属性时,只显示字段验证程序消息?@towpse:如果我理解正确,这与jquery验证使用required属性而不使用新属性有关。你真的不应该复制别人的答案。如果你有什么要补充的,你应该在答案的评论中提出来。很好的解决方案,简单又快速。但是“必须是数字”怎么办?像这样的错误?我起初认为如果验证是在服务器端完成的话,这将不起作用,但在测试之后,它似乎起作用了,至少在通过MVCT进行验证时,每次在模型元数据上看到这些类型的属性时,基本上都会注册要运行的内容。它只是更改验证属性的默认配置。您不必使用特殊属性或类似的东西。这不需要资源文件。您可以使用
attribute.ErrorMessage=“此字段为必填字段,直接分配。
 // Keep the name the same as the original, it helps trigger the original javascript 
 // function for client side validation.

        public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute, IClientValidatable
            {
                public RequiredAttribute()
                {
                    this.ErrorMessage = "Message" // doesnt get called again. only once.
                }

                public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
                {
                    yield return new ModelClientValidationRule
                    {
                        ErrorMessage = "Message", // this gets called on every request, so it's contents can be dynamic.
                        ValidationType = "required"
                    };
                }
            }
    public class LoginModel
    {        
        [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName="RequiredAttribute")]
        [Display(Name = "User name")]
        public string UserName { get; set; }
}
public class MvcApplication : HttpApplication {
    protected void Application_Start() {
        // other stuff here ...
        DataAnnotationsModelValidatorProvider.RegisterAdapter(
            typeof(RequiredAttribute), typeof(CustomRequiredAttributeAdapter));
        DataAnnotationsModelValidatorProvider.RegisterAdapter(
            typeof(StringLengthAttribute), typeof(CustomStringLengthAttributeAdapter));
    }
}

private class CustomRequiredAttributeAdapter : RequiredAttributeAdapter {
    public CustomRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
        : base(metadata, context, attribute)
    {
        attribute.ErrorMessageResourceType = typeof(Resources);
        attribute.ErrorMessageResourceName = "ValRequired";
    }
}

private class CustomStringLengthAttributeAdapter : StringLengthAttributeAdapter {
    public CustomStringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
        : base(metadata, context, attribute)
    {
        attribute.ErrorMessageResourceType = typeof(Resources);
        attribute.ErrorMessageResourceName = "ValStringLength";
    }
}
using Resources;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Web;
using System.Web.Mvc;

public class CustomRequiredAttribute : RequiredAttribute,  IClientValidatable
{
    public CustomRequiredAttribute()
    {
        ErrorMessageResourceType = typeof(ValidationResource);
        ErrorMessageResourceName = "RequiredErrorMessage";
    }


    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {


        yield return new ModelClientValidationRule
        {
            ErrorMessage = GetRequiredMessage(metadata.DisplayName),
            ValidationType = "required"
        };
    }


    private string GetRequiredMessage(string displayName) {

        return displayName + " " + Resources.ValidationResource.RequiredErrorMessageClient;        

    }


}
[CustomRequired]