摘要

  你还在为了验证一个Class对象中很多数据的有效性而写很多If条件判断吗?我也同样遇到这种问题,不过,最近学了一项新的方法,让我不在写很多if条件做判断,通过给属性标注特性来验证数据规则,从此再也不需要写很多If条件判断了。

  最近写C#项目中的时候,在验证数据的有效性的时候写了很多判断,结果工作量很大,然后就想能实现在类属性上标示验证的特性,来验证数据的有效性,以前听说过,但是从来没有实现过,也很少看到在项目中别人使用过,所以就一直没有研究过,但是最近在写Model的时候需要验证很多数据的有效性,所以就想研究一下。

需求:将类属性标示一个验证特性,在使用该类的时候验证数据的有效性,

  我是使用了控制台应用程序做测试,首先我的思路是将Class的属性标示上特性,用来验证属性的数据规则,

这里定义了一个验证特性,主要是来标示属性的最大长度,和当大于最大长度是得提示信息。

  1. /// <summary>
  2. /// 指定数据字段中允许的最小和最大字符长度。
  3. /// </summary>
  4. public class StringLengthAttribute : Attribute
  5. {
  6. /// <summary>
  7. /// 获取或设置字符串的最大长度。
  8. /// </summary>
  9. public int MaximumLength { get; set; }/// <summary>
  10. /// 消息提示
  11. /// </summary>
  12. public string ErrorMessage { get; set; }
  13.  
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. /// <param name="maximumLength"></param>
  18. public StringLengthAttribute(int maximumLength)
  19. {
  20. MaximumLength = maximumLength;
  21. }
  22.  
  23. }

这里是用来验证的类

  1. /// <summary>
  2. /// 数据模型
  3. /// </summary>
  4. public class DataModel : MyIsValid<DataModel>
  5. {
  6. /// <summary>
  7. /// 值
  8. /// </summary>
  9. [StringLength(, ErrorMessage = "Value最大长度为5")]
  10. public string Value { get; set; }
  11. }

然后我就写了一个基类,统统的在基类中做验证。下面是基类的代码,打算以后所有的需要做验证的类,都继承该基类,将属性标识上特性做验证呢(后来发现更好的办法),写的不好,还请多多指教。

  1. public class MyIsValid<T> where T : class
  2. {
  3.  
  4. //验证信息
  5. internal string Msg { get; set; }
  6.  
  7. // 验证是否有效
  8. internal bool IsValid()
  9. {
  10. var v = this as T;
  11.  
  12. Type type = v.GetType();
  13.  
  14. PropertyInfo[] propeties = type.GetProperties();
  15. foreach (PropertyInfo property in propeties)
  16. {
  17. List<Attribute> attributes = property.GetCustomAttributes().ToList();
  18.  
  19. var propertyValue = property.GetValue(v);
  20.  
  21. Attribute stringlength = attributes.FirstOrDefault(p => p.GetType().IsAssignableFrom(typeof(StringLengthAttribute)));
  22.  
  23. if (stringlength == null)
  24. continue;
  25.  
  26. int length = ((StringLengthAttribute)stringlength).MaximumLength;
  27.  
  28. string currentValue = (string)propertyValue;
  29.  
  30. if (currentValue.Length > length)
  31. {
  32. Msg = ((StringLengthAttribute)stringlength).ErrorMessage;
  33. return false;
  34. }
  35. }
  36. return true;
  37. }
  38. }

然后执行结果如图:

执行结果还行,只不过还需要对基类做扩展,支持针对不同的特性做不同的验证。

然后我想到了Asp.Net MVC 里面使用的数据模型绑定技术,然后就想能不能使用它的现有的方法,后来就发现了,“System.ComponentModel.DataAnnotations”这个

具体参考:https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.aspx

然后针对我的需求写了一个扩展方法,如下.(注意一定要引用:System.ComponentModel.DataAnnotations;

  1. public static class ExtensionHelper
  2. {
  3. /// <summary>
  4. /// 验证对象是否有效
  5. /// </summary>
  6. /// <param name="obj">要验证的对象</param>
  7. /// <param name="validationResults"></param>
  8. /// <returns></returns>
  9. public static bool IsValid(this object obj, Collection<ValidationResult> validationResults)
  10. {
  11. return Validator.TryValidateObject(obj, new ValidationContext(obj, null, null), validationResults, true);
  12. }
  13.  
  14. /// <summary>
  15. /// 验证对象是否有效
  16. /// </summary>
  17. /// <param name="obj">要验证的对象</param>
  18. /// <returns></returns>
  19. public static bool IsValid(this object obj)
  20. {
  21. return Validator.TryValidateObject(obj, new ValidationContext(obj, null, null), new Collection<ValidationResult>(), true);
  22. }
  23. }

使用方式如下:

验证相关特性:https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx

也可以自定义,

  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. DataModel r = new DataModel();
  6.  
  7. r.EmailAddress = "cdaimesdfng1m";
  8.  
  9. var v = new Collection<ValidationResult>();
  10.  
  11. if (r.IsValid(v))
  12. {
  13. Console.WriteLine("");
  14. }
  15. else
  16. {
  17. v.ToList().ForEach(e =>
  18. {
  19. Console.WriteLine(e.ErrorMessage);
  20. });
  21. }
  22.  
  23. Console.ReadKey();
  24. }
  25. }
  26.  
  27. public class DataModel
  28. {
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. [Required]
  33. [StringLength(, ErrorMessage = "太大")]
  34. public string Name { get; set; }
  35.  
  36. /// <summary>
  37. ///
  38. /// </summary>
  39. [Range(, )]
  40. public string d { get; set; }
  41.  
  42. /// <summary>
  43. ///
  44. /// </summary>
  45. [EmailAddress]
  46. public string EmailAddress { get; set; }
  47. }

Demo下载地址:http://download.csdn.net/detail/u014265946/9330181

http://tool.nuoeu.com

对System.ComponentModel.DataAnnotations 的学习应用的更多相关文章

  1. System.ComponentModel.DataAnnotations 冲突

    项目从原来的.NET Framework4.0 升级到 .NET Framework4.5 编译报错. 查找原因是: Entity Framework 与 .net4.5 的 System.Compo ...

  2. System.ComponentModel.DataAnnotations.Schema.TableAttribute 同时存在于EntityFramework.dll和System.ComponentModel.DataAnnotations.dll中

    Entity Framework 与 .net4.5 的 System.ComponentModel.DataAnnotations 都有 System.ComponentModel.DataAnno ...

  3. System.ComponentModel.DataAnnotations.Schema 冲突

    System.ComponentModel.DataAnnotations.Schema 冲突 Entity Framework 与 .net4.5 的 System.ComponentModel.D ...

  4. System.ComponentModel.DataAnnotations 命名空间和RequiredAttribute 类

    System.ComponentModel.DataAnnotations 命名空间提供定义 ASP.NET MVC 和 ASP.NET 数据控件的类的特性. RequiredAttribute 指定 ...

  5. 解决EntityFramework与System.ComponentModel.DataAnnotations命名冲突

    比如,定义entity时指定一个外键, [ForeignKey("CustomerID")] public Customer Customer { get; set; } 编译时报 ...

  6. 使用System.ComponentModel.DataAnnotations验证字段数据正确性

    在.NET MVC 中,当页面提交model到Action的时候,自动填充ModelState.使用ModelState.IsValid进行方便快捷的数据验证,其验证也是调用命名空间System.Co ...

  7. C# 特性 System.ComponentModel 命名空间属性方法大全,System.ComponentModel 命名空间的特性

    目录: System.ComponentModel 特性命名空间与常用类 System.ComponentModel.DataAnnotations ComponentModel - Classes ...

  8. “CreateRiaClientFilesTask”任务意外失败。 未能加载文件程序集“System.ComponentModel.DataAnnot...

    错误  77  “CreateRiaClientFilesTask”任务意外失败.  System.Web.HttpException (0x80004005): 未能加载文件或程序集“System. ...

  9. 对于System.Net.Http的学习(三)——使用 HttpClient 检索与获取过程数据

    对于System.Net.Http的学习(一)——System.Net.Http 简介 对于System.Net.Http的学习(二)——使用 HttpClient 进行连接 如何使用 HttpCli ...

随机推荐

  1. Swap in C C++ C# Java

    写一个函数交换两个变量的值. C: 错误的实现: void swap(int i, int j) { int t = i; i = j; j = t; } 因为C语言的函数参数是以值来传递的(pass ...

  2. Jquery Mobile开发以及Js对象动态绑定

    动态创建对象并绑定属性: var instantiate = function (Type, args) { var Constructor = function () { }; Constructo ...

  3. RHCS 6.5 由于resource-agents-3.9.2-40.el6版本过低导致rgmanager[61164]: [fs] umount failed - REBOOTING问题的解决

    問題描述: RHEL 6.5版本RHCS在disable或者relocate service的時候,會導致節點重啟,查看日誌顯示umount掛载點失敗,日誌如下: Nov 29 16:03:50 ph ...

  4. CozyRSS开发记录4-抽屉效果订阅列表栏

    CozyRSS开发记录4-抽屉效果订阅列表栏 1.LeftDrawerContent实现侧滑菜单 抽屉效果,又有人称做侧滑菜单,在手机和平板应用里也是广泛用到.这里,决定把订阅列表栏用抽屉效果实现,而 ...

  5. android:ellipsize的使用(转)

    EidtText和textview中内容过长的话自动换行,使用android:ellipsize与android:singleine可以解决,使只有一行. EditText不支持marquee 用法如 ...

  6. jQuery 中时间显示的模版

    function setTime() {                 var time = new Date();                 var year = time.getFullY ...

  7. Codeforces Round #364 (Div. 2)

    这场是午夜场,发现学长们都睡了,改主意不打了,第二天起来打的virtual contest. A题 http://codeforces.com/problemset/problem/701/A 巨水无 ...

  8. 198个经典C#WinForm实例源码(超赞) 里面的例子 .sln 目录

    \-窗体技巧\QQ窗体\QQFrm.sln; \-窗体技巧\仿XP系统的任务栏菜单\仿XP系统的任务栏菜单.sln; \-窗体技巧\向窗体中拖放图片并显示\向窗体中拖放图片并显示.sln; \-窗体技 ...

  9. Codeforces Round #279 (Div. 2) vector

    A. Team Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  10. 2016 CCPC长春重现赛

    1.2016中国大学生程序设计竞赛(长春)-重现赛 2.总结:会做的太少,应变能力也不行,或者说猜题目的能力不行 02  水 04  HDU 5914  Triangle 1.题意:1~n,n个数,问 ...