本文转自:http://www.cnblogs.com/artech/archive/2012/02/13/NumericPropertyValidation.html

对于一个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: }

现在运行我们的程序就可以得到我们定制的错误消息了。

作者:Artech 出处:http://artech.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
 

[转][ASP.NET MVC]如何定制Numeric属性/字段验证消息的更多相关文章

  1. [ASP.NET MVC]如何定制Numeric属性/字段验证消息

    原文:[ASP.NET MVC]如何定制Numeric属性/字段验证消息 对于一个Numeric属性/字段,ASP.NET MVC会自动进行数据类型的验证(客户端验证),以确保输入的是一个有效的数字, ...

  2. ASP.NET MVC 微信公共平台开发之验证消息的真实性

    ASP.NET MVC 微信公共平台开发 验证消息的真实性 在MVC Controller所在项目中添加过滤器,在过滤器中重写 public override void OnActionExecuti ...

  3. ASP.NET MVC 5 学习教程:添加验证

    原文 ASP.NET MVC 5 学习教程:添加验证 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...

  4. 【译】ASP.NET MVC 5 教程 - 10:添加验证

    原文:[译]ASP.NET MVC 5 教程 - 10:添加验证 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效. DRY 原则 ASP.NET M ...

  5. ASP.NET MVC中对Model进行分步验证的解决方法

    原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...

  6. ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上

    原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...

  7. ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则

    原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...

  8. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

  9. ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

随机推荐

  1. 基于UDP的通讯

    XX:那飘过的100~_~{2014/10/03 10:57} UDP是一种面向非连接SOCK_DGRAM,提供无连接服务.数据包以独立包形式发送,不提供无措保证,数据能够丢失或反复. UDP的Ser ...

  2. 项目实战之玩转div+css制作自己定义形状

    项目需求 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...

  3. 《The Swift Programming Language》的笔记-第28页

    页 本页里的主要内容是: 1 介绍swift语言里的各类数制,或者说某一整数的不同表示形式. 1)十进制,无前缀 的序列 3)八进制,以0o开头.后边是若干0~7的序列 进制,以0x开头.后是0~9. ...

  4. qt之旅-1纯手写Qt界面

    通过手写qt代码来认识qt程序的构成,以及特性.设计一个查找对话框.以下是设计过程 1 新建一个empty qt project 2 配置pro文件 HEADERS += \ Find.h QT += ...

  5. 不等式数列 DP

    度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 '>' 和 '<' )使其成为一个合法的不等式数列.但是现在度度熊手中只有 ...

  6. http的session和cookie

    1 http session和http请求之间的关系 http协议是无状态的,一次会话服务端需要处理多次http请求,就算是长连接,也是要发送多次请求的,由于http无状态所有每次的请求都是独立的,服 ...

  7. 常用的Atom插件

    1.simplified-chinese-menu 2.tree-view-finder 3.minimap 4.linter和linter-jshint 5.linter-js-standard 6 ...

  8. Js_闭包详解

    http://blog.csdn.net/chenglc1612/article/details/53413318 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变 ...

  9. POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分

    题目链接:https://vjudge.net/problem/POJ-2112 Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K T ...

  10. 关于页面上输入框中 空格 、0 、NULL 的处理 示例

    ep.setPositionNum(get("positionNum").toString()); ep.setClasstype(get("classtype" ...