.NET中特性+反射 实现数据校验

在.NET中,我们可以使用特性+反射来实现数据校验。特性是一种用于为程序中的代码添加元数据的机制。元数据是与程序中的代码相关联的数据,但不直接成为代码的一部分。通过特性,我们可以为类、方法、属性等添加额外的信息,这些信息可以在运行时通过反射获取和使用。

对反射不太熟悉的小伙伴可以去看我以前的文章 .NET中的反射

为了实现数据校验,我们可以定义一个自定义特性,并将其应用于需要校验的属性或参数上。然后,我们可以编写代码来检查这些特性,并根据特性的配置执行相应的校验逻辑。

示例代码

定义自定义特性

using System;
using System.ComponentModel.DataAnnotations; [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class ValidationAttribute : Attribute
{
public string ErrorMessage { get; set; } public ValidationAttribute(string errorMessage)
{
ErrorMessage = errorMessage;
}
}

定义具体的校验特性

[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class RequiredAttribute : ValidationAttribute
{
public RequiredAttribute() : base("该字段是必填项。") { }
} [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class RangeAttribute : ValidationAttribute
{
public int Minimum { get; set; }
public int Maximum { get; set; } public RangeAttribute(int minimum, int maximum, string errorMessage = "该字段的值必须在 {0} 和 {1} 之间。")
: base(errorMessage)
{
Minimum = minimum;
Maximum = maximum;
}
}

在模型类中使用这些特性

public class Person
{
[Required]
public string Name { get; set; } [Range(18, 100, ErrorMessage = "年龄必须在 18 到 100 之间。")]
public int Age { get; set; }
}

编写验证方法

public class Validator
{
public static bool Validate<T>(T obj, out string errorMessage)
{
errorMessage = null;
var type = typeof(T);
var properties = type.GetProperties(); foreach (var property in properties)
{
var validationAttributes = property.GetCustomAttributes(typeof(ValidationAttribute), true); foreach (var attribute in validationAttributes)
{
var value = property.GetValue(obj); switch (attribute)
{
case RequiredAttribute required:
if (value == null || (value is string str && string.IsNullOrWhiteSpace(str)))
{
errorMessage = required.ErrorMessage;
return false;
}
break;
case RangeAttribute range:
if (value is IComparable comparable)
{
if (comparable.CompareTo(range.Minimum) < 0 || comparable.CompareTo(range.Maximum) > 0)
{
errorMessage = string.Format(range.ErrorMessage, range.Minimum, range.Maximum);
return false;
}
}
break;
// 可以添加更多校验特性类型
}
}
} return true;
}
}

使用Validator类来校验Person对象

class Program
{
static void Main(string[] args)
{
var person = new Person { Name = "张三", Age = 15 };
string errorMessage;
bool isValid = Validator.Validate(person, out errorMessage);
if (!isValid)
{
Console.WriteLine(errorMessage); // 输出:该字段是必填项。
}
Console.ReadLine();
}
}

说明

这个示例演示了如何使用特性和反射实现基本的数据校验。在实际应用中,你可能需要处理更复杂的校验逻辑和更多的校验类型。

此外,还可以使用现有的数据特性(如System.ComponentModel.DataAnnotations命名空间中的特性)来简化校验过程。

以下是该命名空间中一些常用的特性(Attribute),以及它们的用途:

特性名称 用途
[Required] 确保属性值不为空(不为 null 且对于字符串不是空字符串)。
[StringLength] 限制字符串属性的最大长度。
[Range] 确保数值型属性在指定的范围内。
[Minimum] 确保数值型属性不小于指定的最小值。
[Maximum] 确保数值型属性不大于指定的最大值。
[RegularExpression] 通过正则表达式验证属性值的格式。
[EmailAddress] 验证属性值是否为有效的电子邮件地址。
[Url] 验证属性值是否为有效的 URL。
[Phone] 验证属性值是否为有效的电话号码。
[CreditCard] 验证属性值是否为有效的信用卡号。
[Compare] 比较两个属性值是否相等,常用于密码和确认密码的字段。
[DataType] 指定数据的类型,例如日期、时间、电话号码等,并不验证数据,而是提供给数据绑定机制。
[CustomValidation] 允许指定自定义验证逻辑。
[EnumDataType] 验证属性值是否为指定枚举类型中的有效成员。
[StringLength] 验证字符串长度是否在指定的范围内。

这些特性通常与ASP.NET Core或是ASP.NET MVC、Entity Framework等框架结合使用。

使用这些特性可以大大简化数据验证的代码,并且使验证逻辑与业务逻辑分离,提高代码的可维护性和可读性。

.NET中特性+反射 实现数据校验的更多相关文章

  1. SpringMVC中的 JSR 303 数据校验框架说明

    JSR 303 是java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE 6.0中. JSR 303 通过在Bean属性上标注类似于@NotNull.@Max等标准的注解指定校验规则 ...

  2. wpf企业应用之数据校验

    wpf中使用IDataErrorInfo实现数据校验,绑定实体需要实现了此接口,并在UI绑定表达式中添加ValidatesOnDataErrors=True,这样数据校验发生时,wpf会调用该接口中的 ...

  3. [WPF 基础知识系列] —— 绑定中的数据校验Vaildation

    前言: 只要是有表单存在,那么就有可能有对数据的校验需求.如:判断是否为整数.判断电子邮件格式等等. WPF采用一种全新的方式 - Binding,来实现前台显示与后台数据进行交互,当然数据校验方式也 ...

  4. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  5. struts2:数据校验,通过Action中的validate()方法实现校验,图解

    根据输入校验的处理场所的不同,可以将输入校验分为客户端校验和服务器端校验两种.服务器端验证目前有两种方式: 第一种 Struts2中提供了一个com.opensymphony.xwork2.Valid ...

  6. struts2:数据校验,通过Action中的validate()方法实现校验(续:多业务方法时的不同验证处理)

    前文:struts2:数据校验,通过Action中的validate()方法实现校验,图解 如果定义的Action中存在多个逻辑处理方法,且不同的处理逻辑可能需要不同的校验规则,在这种情况下,就需要通 ...

  7. struts中的数据校验

    1.struts中如何进行数据校验 在每一个Action类中,数据校验一般都写在业务方法中,比如login().register()等.struts提供了数据校验功能.每个继承自ActionSuppo ...

  8. Struts2中validate数据校验的两种常用方法

    本文主要介绍Struts2中validate数据校验的两种方法及Struts2常用校验器.  1.Action中的validate()方法 Struts2提供了一个Validateable接口,这个接 ...

  9. 利用kettle中的JS来完成ETL数据校验

    最近参与了一个信托行业的BI项目,由于信托业务系统设计的问题,很多都是用户手工录入的数据,也有一些是需要分析的但是用户没有录入的数据,针对这样的数据质量,我们就要在ETL抽取的过程中来对数据流进行校验 ...

  10. C#中不同格式数据校验的正则表达式

    网上经常看到用正则表达式校验数据的文章,有的虽然总结得很全,但是大多数都没有经过严格验证,错误较多. 本文包含三十余条不同格式数据校验的C#正则表达式,一般均附有说明,且在Visual Studio里 ...

随机推荐

  1. 国产Linux发行版 Deepin 评价与主观展望 我与Deepin的故事

    全文皆属于up自己的主观臆断,有不到之处可以进行批评,共同成长. P1 编辑时间(2021-2-20) 昨天,我刷b站的时候见到一则旧闻,关于我国操作系统的.原本只是想写个1000字左右的评论的,没想 ...

  2. c# 托管和非托管资源-详解

    前言 引用:带你复习c# 托管和非托管资源_C#教程_脚本之家 (jb51.net) c# 托管和非托管比较重要,因为这涉及到资源的释放. 现在只要在计算机上运行的,无论玩出什么花来,整个什么概念,逃 ...

  3. redis 简单整理——客户端案例分析[十八]

    前言 简单整理一下客户端案例分析. 正文 现象一: 服务端现象:Redis主节点内存陡增,几乎用满maxmemory,而从节点 内存并没有变化. 客户端现象:客户端产生了OOM异常,也就是Redis主 ...

  4. echarts使用与踩坑

    0.踩坑点 1.当图表不显示在页面(display:none)执行resize可能会导致图表样式混乱 1. 官网示例 import * as echarts from 'echarts'; // 基于 ...

  5. 探索Kimi智能助手:如何用超长文本解锁高效信息处理新境界

    目前,Kimi备受瞩目,不仅在社交平台上引起了广泛关注,而且在解决我们的实际问题方面也显示出了巨大潜力.其支持超长文本的特性使得我们能够更加灵活地配置信息,避免了频繁与向量数据库进行交互以及编写提示词 ...

  6. portainer安装,配置,使用

    Portainer安装 Portainer是Docker容器管理可视化界面,主要是可以通过可视化界面创建,管理Dockert容器,并且支持多个节点管理(免费版支持五个节点). Portainer官网地 ...

  7. EasyCV带你复现更好更快的自监督算法-FastConvMAE

    简介: 近期FastConvMAE工作在EasyCV框架内首次对外开源,本文将重点介绍ConvMAE和FastConvMAE的主要工作,以及对应的代码实现,最后提供详细的教程示例如何进行FastCon ...

  8. K8s 网关选型初判:Nginx 还是 Envoy?

    简介: 本文将从性能和成本.可靠性.安全性 3 方面,对两大开源实现进行比对,希望对正在做 K8s 网关选型的企业有所借鉴. 作者:张添翼(澄潭) 为了避免混淆,我们先对一些关键定义做一些厘清: 传统 ...

  9. 2018-7-15-WPF-在-DrawingContext-的-push-如何使用

    title author date CreateTime categories WPF 在 DrawingContext 的 push 如何使用 lindexi 2018-7-15 15:51:0 + ...

  10. 2018-8-29-dotnet-core-添加-SublimeText-编译插件

    title author date CreateTime categories dotnet core 添加 SublimeText 编译插件 lindexi 2018-08-29 08:53:47 ...