如何定制Numeric属性/字段验证消息

如题所述

  一、针对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。

  image

  二、默认的验证消息来源于何处?
  针对数字类型字段进行验证的是一个名称为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: }
温馨提示:内容为网友见解,仅供参考
无其他回答

如何定制Numeric属性\/字段验证消息
一、针对Numeric属性\/字段默认验证消息 我们先来通过一个简单的例子来验证这个问题,为此我们定义了如下一个表示员工信息的Employee类型,其中代表年龄的Age属性类型为整型。1: public class Employee 2: { 3: [Display(Name = "姓名")]4: public string Name { get; set; } 5:6: [Disp...

SQL数据库中Numeric(10,2)是什么意思?
SQL数据库中Numeric(10,2)是指字段是数值型,Numeric(10,2)表示总位数为10,小数点后为2位的数,也就是说这个字段的整数位最大是8位。SQL中的五种数据类型:字符型,文本型,数值型,逻辑型和日期型 numeric(p,s) p 为精度(有效位),表示可储存数值的最大位数,小数点左右两侧都包括在内,...

c# winforms NumericUpDown 关于值的验证问题
Maximun也绑定到数据上不就行了 我真不知道你需要问的是什么,你是控件使用有问题还是?如果你用了绑定了而且用了属性就不要用ValueChanged了

SQL数据库中Numeric(10,2)是什么意思?
4、逻辑型(BIT)如果使用复选框(CHECKBOX)从网页中搜集信息,可以把此信息存储在BIT型字段中。BIT型字段只能取两个值:0或1。注意,在创建好一个表之后,不能向表中添加BIT型字段。如果你打算在一个表中包含BIT型字段,你必须在创建表时完成。5、日期型(DATETIMEVSSMALLDATETIME)一个DATETIME型的...

SQL数据库中Numeric(10,2)是什么意思?
二、文本型TEXT使用文本型数据,可以存放超过二十亿个字符的字符串。当需要存储大串的字符时,应该使用文本型数据。三、数值型SQL支持许多种不同的数值型数据。可以存储整数 INT 、小数 NUMERIC、和钱数 MONEY。四、逻辑型 如果使用复选框( CHECKBOX)从网页中搜集信息,可以把此信息存储在BIT型字段中...

正则表达式:(.*?) 获取的内容如何才能不含和
1、RegExp对象是最重要的一个对象,它有几个属性,其中: ○Global 属性,设置或返回一个 Boolean 值,该值指明在整个搜索字符串时模式是全部匹配还是只匹配第一个。如果搜索应用于整个字符串,Global 属性的值为 True,否则其值为 False。默认的设置为 False。 ○IgnoreCase 属性,设置或返回一个Boolean值,指明模式搜索...

access某表时间字段里的有效性规则为只能输入系统日期前一年五月一日...
文本型(Text):默认数据类型,最多255个字符,常用于存储字符信息,如姓名、地址等。通过设置“字段大小”可以限制输入字符数。备注型(Memo):可存储大量文本,最多65,535个字符,适合详细描述或个人简历等较长内容。数字型(Numeric):包括整型、长整型、字节型、单精度型和双精度型,用于数值运算。

sql排序问题,字符串中有全数字和含中文的, 要求全数字的转换成整数排...
使用 ISNUMERIC函数就可以了,order by ISNUMERIC(字段),case when ISNUMERIC(字段)=0 then 0 else cast(字段 as bigint) end 还有小数的!!晕。那就把bigint改成 float order by ISNUMERIC(字段),case when ISNUMERIC(字段)=0 then 0 else cast(字段 as float) end ...

yii框架中rulees函数中的safe是怎样用的呢?
required”,这种的就是必填,“numeric”这种就是数字一样,因为对于yii的对象的属性赋值然后进行保存的时候会进行验证,如果字段在这个rules里面不存在,那么报错的时候这个字段对应的值是保存不进去的,这个时候如果这个字段不想被验证,那么一般情况下就会放在safe里面,表示是安全字段。

将数据类型 varchar 转换为 numeric 时出错
numeric 是数值类型,看你插入的都是字符..所以,你要在有numeric那一列插入数值.

相似回答