[ASP.NET MVC]如何定制Numeric属性/字段验证消息
原文:[ASP.NET MVC]如何定制Numeric属性/字段验证消息
对于一个Numeric属性/字段,ASP.NET MVC会自动进行数据类型的验证(客户端验证),以确保输入的是一个有效的数字,但是呈现在页面上的错误消息总是一段固定的文本:“The field {0} must be a number”,本篇提供一种解决方案使我们可以对此验证消息进行定制。[源代码从这里下载]
目录
一、针对Numeric属性/字段默认验证消息
二、默认的验证消息来源于何处?
三、通过自定义ModelValidatorProvider替换NumericModelValidator
四、注册自定义ModelValidatorProvider
一、针对Numeric属性/字段默认验证消息
我们先来通过一个简单的例子来验证这个问题,为此我们定义了如下一个表示员工信息的Employee类型,其中代表年龄的Age属性类型为整型。
1: public class Employee
2: {
3: [Display(Name = "姓名")]
4: public string Name { get; set; }
5:
6: [Display(Name = "性别")]
7: public string Gender { get; set; }
8:
9: [Display(Name = "年龄")]
10: public int Age { get; set; }
11: }
我们创建一个Model类型为Employee的View对某个元员工的信息进行修改。如下图所示,当我们输入一个非数字字符串作为Age字段的时候,验证错误信息显示为“The field 年龄 must be a number”,值得一提的是:当前线程的CurrentUICulture为zh-CN。

二、默认的验证消息来源于何处?
针对数字类型字段进行验证的是一个名称为NumericModelValidator的ModelValidator,不过这是个定义在System.Web.Mvc程序集中俄内部类型。如果采用Reflector查看其定义,可以发现用于返回错误消息的方法是一个名为MakeErrorString的静态方法。如下面的代码所示,作为错误消息的字符串来源于内嵌于程序集中的资源文件。
1: internal sealed class NumericModelValidator : ModelValidator
2: {
3: //其他成员
4: private static string MakeErrorString(string displayName)
5: {
6: return string.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, new object[] { displayName });
7: }
8: }
NumericModelValidator最终是通过ClientDataTypeModelValidatorProvider这个一个ModelValidatorProvider提供的。
三、通过自定义ModelValidatorProvider替换NumericModelValidator
如果我们想改变内部类型NumericModelValidator的错误消息,可以通过将ClientDataTypeModelValidatorProvider提供的NumericModelValidator替换成另一个ModelValidator。在这里我们替换的是一个DataAnnotationsModelValidator,而它基于的ValidationAttribute是我们自定义的NumericAttribute。
如下面的代码片断所示,内部类型NumericAttribute是ValidationAttribute的子类,并且实现了IClientValidatable接口。在这里我么只考虑客户端验证,所以重写的IsValid方法直接返回True,而GetClientValidationRules方法则返回一个包含一个验证类型为“number”的ModelClientValidationRule对象的集合。我们使用FormatErrorMessage方法格式化后的字符串作为ModelClientValidationRule的ErrorMessage属性。
1: internal class NumericAttribute : ValidationAttribute, IClientValidatable
2: {
3: public override bool IsValid(object value)
4: {
5: return true;
6: }
7: public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
8: {
9: yield return new ModelClientValidationRule { ValidationType = "number", ErrorMessage = this.FormatErrorMessage(metadata.DisplayName)};
10: }
11: }
现在我们需要做的就是通过一个自定义ModelValidatorProvider将ClientDataTypeModelValidatorProvider提供的NumericModelValidator替换成基于NumericAttribute的DataAnnotationsModelValidator,所以我们定义了一个直接继承自ClientDataTypeModelValidatorProvider的FilterableClientDataTypeModelValidatorProvider。如下面的代码所示,在重写的GetValidators方法中我们完成了针对NumericModelValidator的替换。对于被创建的NumericAttribute来说,我们指定的错误消息也定义在Resource文件中(为了提供多语言的支持),而基于zh的内容为“{0}必须是一个数字!”。
1: public class FilterableClientDataTypeModelValidatorProvider : ClientDataTypeModelValidatorProvider
2: {
3: public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
4: {
5: var allValidators = base.GetValidators(metadata, context);
6: var validators = new List<ModelValidator>();
7: foreach (var v in allValidators)
8: {
9: if (v.GetType().Name != "NumericModelValidator")
10: {
11: validators.Add(v);
12: }
13: else
14: {
15: NumericAttribute attribute = new NumericAttribute{ ErrorMessage = Resources.FieldMustBeNumeric};
16: DataAnnotationsModelValidator validator = new DataAnnotationsModelValidator(metadata, context, attribute);
17: validators.Add(validator);
18: }
19: }
20: return validators;
21: }
22: }
四、注册自定义ModelValidatorProvider
现在我们只需要通过ModelValidatorProvider的注册让我们自定义的FilterableClientDataTypeModelValidatorProvider替换默认的ClientDataTypeModelValidatorProvider。在Global.asax中,针对FilterableClientDataTypeModelValidatorProvider的注册可以通过如下的代码来完成。
1: public class MvcApplication : System.Web.HttpApplication
2: {
3: //其他成员
4: protected void Application_Start()
5: {
6: //其他操作
7: var clientDataTypeValidator = ModelValidatorProviders.Providers.OfType<ClientDataTypeModelValidatorProvider>().FirstOrDefault();
8: if (null != clientDataTypeValidator)
9: {
10: ModelValidatorProviders.Providers.Remove(clientDataTypeValidator);
11: }
12: ModelValidatorProviders.Providers.Add(new FilterableClientDataTypeModelValidatorProvider());
13: }
14: }
现在运行我们的程序就可以得到我们定制的错误消息了。

[ASP.NET MVC]如何定制Numeric属性/字段验证消息的更多相关文章
- [转][ASP.NET MVC]如何定制Numeric属性/字段验证消息
本文转自:http://www.cnblogs.com/artech/archive/2012/02/13/NumericPropertyValidation.html 对于一个Numeric属性/字 ...
- ASP.NET MVC 微信公共平台开发之验证消息的真实性
ASP.NET MVC 微信公共平台开发 验证消息的真实性 在MVC Controller所在项目中添加过滤器,在过滤器中重写 public override void OnActionExecuti ...
- ASP.NET MVC 5 学习教程:添加验证
原文 ASP.NET MVC 5 学习教程:添加验证 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...
- 【译】ASP.NET MVC 5 教程 - 10:添加验证
原文:[译]ASP.NET MVC 5 教程 - 10:添加验证 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效. DRY 原则 ASP.NET M ...
- ASP.NET MVC中对Model进行分步验证的解决方法
原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...
- ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证
随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...
- ASP.NET MVC使用Oauth2.0实现身份验证
随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...
随机推荐
- [LeetCode] Search in Rotated Sorted Array II [36]
称号 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...
- BZOJ 2435 NOI2011 道路建设 BFS/DFS
标题效果:给定一个树(直接将树.不要贪图生成树图!).寻找每条边权值*分差的两侧之间 BFS水必须是能 竟DFS能够住...系统堆栈可能有些不够,我们可以使用内联汇编手册中大型系统堆栈 详见代码 这个 ...
- Android之Handler的postDelayed()使用方法
这是一种创建多线程信息功能 用法: 1,首先创建一个Handler物 Handler handler=new Handler(); 2.然后创建一个Runnable物 Runnable runnabl ...
- Java-如何去掉JFrame上的最大化最小化和关闭按钮(转)
在JDK1.4以前,我们只有一种方式来去掉窗口的标题栏,那就是直接使用JWindow,用JWindow来代替JFrame使用.但用过JWindow的人一定知道,JWindow在操作系统的任务栏是不可见 ...
- HTTP状态管理机制之Cookie(转)
一.cookie 起源 cookie 最早是网景公司的雇员 Lou Montulli 在1993年3月发明,后被 W3C 采纳,目前 cookie 已经成为标准,所有的主流浏览器如 IE.Chrome ...
- 算法----选择排序(select sort)
排序不是一个时间的数组进行排序,找到最小的元素,其与阵列的第一个元素交换,因此,排序的数组. 算法: void sort::select_sort(int* a,const int n) { for( ...
- FPGA图案--数字表示(代码+波形)
在数字逻辑系统,仅仅存在高低.所以用它只代表一个整数数字.并且有3代表性的种类.这是:原码表示(符号加绝对值值).反码表示(加-minus标志)而补码(符号加补).这三个在FPGA中都有着广泛的应用. ...
- 树莓派的演奏音符3 -- LCD1602显示文章
LCD1602它是低-cost输出装置.它具有体积小.简单的操作.低功耗优势.因此,在一些DIY 用它来输出关于产品的一些信息. 昨日在使用,尽管平局网上资源,但仍存在一些问题,确处理. 一.LCD1 ...
- Java回合阵列List
package com.mine.practice.arrtolist; import java.util.ArrayList; import java.util.Arrays; import jav ...
- ubuntu 14.04 安装搜狗拼音输入法
原文:ubuntu 14.04 安装搜狗拼音输入法 ubuntu桌面系统下终于有了好用的拼音法-搜狗拼音输入法,欲在ubuntu 14.04下安装搜狗拼音输入法相当的简单. 先到搜狗拼音官网下载对应的 ...