MVC:覆盖默认的ValidationMessage
-
05-07-2019 - |
题
在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 +&quot; Blah Blah“,没有用
之类的东西注释所有属性[Required(ErrorMessage = "First Name Blah Blah")]
干杯,
ETFairfax
解决方案
public class GenericRequired: RequiredAttribute
{
public GenericRequired()
{
this.ErrorMessage = "{0} Blah blah";
}
}
其他提示
这是一种在没有子类化 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 =&quot; Field Name&quot;)]
设置该字段的名称。
似乎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"
};
}
}
只需更改
[Required]
到
[Required(ErrorMessage = "Your Message, Bla bla bla aaa!")]
编辑:我发布了这个因为我正在寻找具有[必需]属性的此解决方案,并且遇到问题需要找到它。创建新的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; }
}
您可以编写自己的属性:
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的副本,其中包含更改的错误消息。
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
现在使用数据注释
[CustomRequired]
这对我有用。仔细阅读代码中的注释。 (根据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"
};
}
}