当前位置: 首页 > news >正文

ASP.NET MVC 2 验证消息本地化策略扩展

ASP.NET MVC2 结合System.ComponentModel.DataAnnotations 提供了一套非常有效的实体验证框架。对于错误信息的处理,它默认提供了两种选择:

  1. 字符串常量
  2. 从程序集资源文件读取

但是在我们这里,我们有一套自己的资源文件方案,也就是我们需要自己控件错误信息的本地化操作。由于在元数据,我们只能提供常量,无法进行字符串操作。一种比较直接和麻烦的办法就是重写所有的验证规则,在验证规则中对字符串常量进行本地化操作。

[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class CustomValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
{
    public CustomValidationAttribute(string message)
        : base(() => message.Localize())
    {
    }
}

但是这样做,一方面会比较麻烦,所有的验证规则我们都要进行重写;另一方面我们在设计model时就是特别的小心使用我们自己重写过的规则才能达到我们的目的,这将大大降低开发体验。为此,今天特别再次对照MVC2的源码,希望能找到一个可用的扩展点来解决这个问题。最终发现我们可以通过重写DataAnnotationsModelValidatorProvider的GetValidators方法来达到我们希望的效果:

public class CustomDataAnnotationsModelValidatorProvider : System.Web.Mvc.DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        foreach (ValidationAttribute attribute in attributes.OfType<ValidationAttribute>())
        {
            if (!string.IsNullOrWhiteSpace(attribute.ErrorMessage))
            {
                attribute.ErrorMessage = attribute.ErrorMessage.Localize();
            }

        }

        var validators = base.GetValidators(metadata, context, attributes);

        return validators;
    }
}

代码非常简单,我们只是在调用GetValidators方法之前,对attribute的错误消息进行一次本地化操作处理即可。通过这一次处理,我们可以同步处理客户端验证消息和服务器端验证消息的本地化。下面的工作就是用这个Provider来代替它的父类,在Global.asax添加下面的代码即可完成:

 

ModelValidatorProviders.Providers.RemoveAt(0);
ModelValidatorProviders.Providers.Insert(0, new CustomDataAnnotationsModelValidatorProvider());

通过这样一个小小的扩展,就可以很完美的达到我们的目的。不过,为了这个小扩展,却花费了我们不少的时间。

相关文章:

  • Google code上利用SVN托管代码
  • si470x驱动调试工作总结
  • For命令在Windows中的妙用
  • Oracle 10g Audit(审计) --- 记录登录用户在Oracle中的所有操作(转)
  • 防止电脑被******的方法
  • 禁用beep重定向
  • 白平衡(转载自wikipedia)
  • 母校,其实也很好,只是当时不知道珍惜
  • Knights of the Round Table--POJ 2942
  • 默认mysql安装路径
  • 【项目分析】通用的枚举类型的下拉列表绑定(3)
  • 电信无线网卡启动参数
  • Josephus 约瑟夫 问题
  • VS2008安装boost(手记)
  • Excel2010重复打印标题行
  • Angular6错误 Service: No provider for Renderer2
  • Brief introduction of how to 'Call, Apply and Bind'
  • ES6核心特性
  • FastReport在线报表设计器工作原理
  • HashMap剖析之内部结构
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • js继承的实现方法
  • MQ框架的比较
  • SOFAMosn配置模型
  • SpriteKit 技巧之添加背景图片
  • vue总结
  • Web设计流程优化:网页效果图设计新思路
  • 产品三维模型在线预览
  • 仿天猫超市收藏抛物线动画工具库
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 回顾2016
  • 前端路由实现-history
  • 驱动程序原理
  • 入口文件开始,分析Vue源码实现
  • 一个JAVA程序员成长之路分享
  • AI算硅基生命吗,为什么?
  • #{}和${}的区别?
  • #WEB前端(HTML属性)
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (初研) Sentence-embedding fine-tune notebook
  • (第一天)包装对象、作用域、创建对象
  • (独孤九剑)--文件系统
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)http-server应用
  • (转)shell调试方法
  • .net 设置默认首页
  • .NET学习全景图
  • .NET中使用Redis (二)
  • /bin、/sbin、/usr/bin、/usr/sbin