MVC:覆盖默认的ValidationMessage

时间:2009-11-27 10:59:44

标签: 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.ValidationMessage("FirstName", "*") %>

我的问题:如果我在没有提供名称的情况下提交此表单,我会收到以下消息“FirstName字段是必需的”

行。所以,我去改变我的财产......

[DisplayName("First Name")]
[Required]
public string FirstName{ get; set; }    

..现在获得“首字母字段是必需的”

到目前为止一切都很好。

所以现在我希望错误信息显示“First Name Blah Blah”。如何覆盖默认消息以显示DisplayName +“Blah Blah”,不用

等注释所有属性
[Required(ErrorMessage = "First Name Blah Blah")]

干杯,

ETFairfax

8 个答案:

答案 0 :(得分:16)

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

答案 1 :(得分:13)

这是一种在没有子类化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")]设置该字段。

答案 2 :(得分:12)

似乎RequiredAttribute没有实现IClientValidatable,因此如果覆盖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"
        };
    }
}

答案 3 :(得分:2)

只需更改

[Required] 

[Required(ErrorMessage = "Your Message, Bla bla bla aaa!")]

答案 4 :(得分:1)

编辑:我发布了这个因为我正在寻找具有[必需]属性的此解决方案,并且遇到问题需要找到它。创建新的Q / A看起来并不好,因为这个问题已经存在。

我试图解决同样的问题,我在MVC 4中找到了非常简单的解决方案。

首先,您可能必须在某些地方存储错误消息。我使用了http://afana.me/post/aspnet-mvc-internationalization.aspx中详细描述的自定义资源。

重要的是,我可以通过简单地调用 ResourcesProject.Resources.SomeCustomError ResourcesProject.Resources.MainPageTitle 等来获取任何资源(甚至是错误消息)。每次我尝试要访问Resources类,它需要从当前线程获取文化信息并返回正确的语言。

我在 ResourcesProject.Resources.RequiredAttribute 中有字段验证的错误消息。要将此消息设置为在View中显示,只需使用这两个参数更新[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; }
}

答案 5 :(得分:0)

您可以编写自己的属性:

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的副本,其中包含更改的错误消息。

答案 6 :(得分:0)

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;        

    }


}

App_GlobalResources文件/ ValidationResource.resx

enter image description here

现在使用数据注释

[CustomRequired]

答案 7 :(得分:-1)

这对我有用。仔细阅读代码中的注释。 (根据Chad的回答)。

 // 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"
                    };
                }
            }