首页 程序笔记 Attribute特性封装通用数据验证

Attribute特性封装通用数据验证

在接口接收数据或者数据库写入的时候一般都会进行数据验证。如果在接收到数据或者插入的时候对对象的每个属性进行检验,代码会很臃肿,而且无法复用,通过Attribute特性可以优雅地进行数据验证。

例如我们写一个特性验证属性不能为空,示例代码如下:

特性RequiredAttribute

public class RequiredAttribute:Attribute
{
}

public class User
{
    [Required]//非空校验特性标注
    public string NickName { get; set; }
    public int? Level { get; set; }
}

写一个扩展方法,对对象进行数据验证

//扩展方法
public static bool Validate(this object obj)
{
    var type = obj.GetType();
    foreach (var prop in type.GetProperties())
    {
        if (prop.IsDefined(typeof(RequiredAttribute), true))
        {
            var propValue = prop.GetValue(obj);
            if (propValue == null || string.IsNullOrWhiteSpace(propValue.ToString())) {
                return false;
            }
        }
    }
    return true;
}
//调用扩展方法进行数据验证
User user = new User()
{
    NickName = "Paul",
    Level = 1
};
//获得校验结果true or false,可以在适当的地方先进行校验再执行后续操作
var result = user.Validate()

像这样就能实现通过Attribute特性封装通用数据验证了,如果别的字段想要做验证,加上这个标签就可以了。原理就是这样,那么要加一些别的复杂的数据验证都可以通过增加Attribute特性来实现。

如果按照上面的写法,每次增加特性后,都要修改扩展方法,我们可以设计一下,让每个特性自己完成检验。定义一个抽象特性,然后每次要增加新的验证就继承它,并且重写它的验证方法。下面我再增加一个验证字符串长度的特性,然后通过更加优雅的方式是实现它,代码如下:

public abstract class AbstracValidateAttribute:Attribute
{
    public abstract bool Validate(object obj);
}
//验证非空
public class RequiredAttribute:AbstracValidateAttribute
{
    //重写验证方法
    public override bool Validate(object obj) {
        return (obj == null || string.IsNullOrWhiteSpace(obj.ToString())) ? false : true;
    }
}
//验证字符串长度
public class StringLengthAttribute:AbstracValidateAttribute
{
    private int _Min { get; set; }
    private int _Max { get; set; }
    public StringLengthAttribute(int min, int max) {
        _Min = min;
        _Max = max;
    }
    public override bool Validate(object obj)
    {
        if (obj == null || string.IsNullOrWhiteSpace(obj.ToString()))
            return false;
        var str = obj.ToString();
        return (str.Length < _Min || str.Length > _Max) ? false : true;
    }
}

public class User
{
    [Required]//非空校验特性标注
    [StringLength(1,10)]//字符串长度1-10
    public string NickName { get; set; }
    public int? Level { get; set; }
}

扩展方法修改为:

public static bool Validate(this object obj) {
    var type = obj.GetType();
    foreach (var prop in type.GetProperties()) {
        if (prop.IsDefined(typeof(AbstracValidateAttribute), true)) {
            var propValue = prop.GetValue(obj);
            var attributeArray = prop.GetCustomAttributes<AbstracValidateAttribute>();
            foreach (var item in attributeArray) {
                if (!item.Validate(propValue))
                    return false;
            }
        }
    }
    return true;
}

这样一来,以后再要加验证方式的时候,新增一个特性Attribute继承AbstracValidateAttribute,然后重写Validate方法,就可以自定义一个数据验证规则了。无需修改扩展方法,直接给属性加上特性标注即可。

1

站心网

在接口接收数据或者数据库写入的时候一般都会进行数据验证。如果在接收到数据或者插入的时候对对象的每个属..

为您推荐

实时数据的处理一致性如何保证?

实时数据一致性的定义以及面临的挑战数据一致性通常指的是数据在整个系统或多个系统中保持准确、可靠和同步的状态。在实时数据处理中,一致性包括但不限于数据的准确性、完整性、时效性和顺序性。下图是典型的实时/..

关于大数据的一些真知灼见

大数据很强大,但还是有很多人仍然不知道它到底是什么。让我们来学习大数据的真实表现,以及如何更好地促进企业转型。或许我们经常听到有人讲大数据,但仍然有很多人不知道它到底是什么。因为我确信它很强大,所以我..

.net环境下跨进程、高频率读写数据

一、需求背景1、最近项目要求高频次地读写数据,数据量也不是很大,多表总共加起来在百万条上下。单表最大的也在25万左右,历史数据表因为不涉及所以不用考虑,难点在于这个规模的热点数据,变化非常频繁。数据来源..

工作中人们常提到的数据预处理,说的到底是什么?

数据预处理一方面是为了提高数据的质量,另一方面也是为了适应所做数据分析的软件或者方法。在做数据分析时,我想许多数据分析师会像《R语言实战第二版》的作者卡巴科弗那样发出感叹:“数据分析师在数据预处理上花..

优秀软件工程师必备的7大特性

不是每一个程序员都能成为优秀的软件工程师。在过去的6年时间里,我在Ooyala、Quora和now Quip这3个创业公司面试过许许多多挺有发展潜力的“种子选手”,他们都有着5年以上的工作经验,并且曾为类似于谷歌这样的顶级..

C#使用 Attribute 实现 AOP 功能

在 C# 中,通过自定义 Attribute 并结合一些技术(如动态代理、反射等)可以实现 AOP(面向切面编程)。AOP 通常用于日志记录、性能监控、权限验证等横切关注点。以下是一个使用 C# Attribute 实现 AOP 功能的示例。..

mysql随机获取一条或者多条数据

语句一:select * from users order by rand() LIMIT 1MYSQL手册里面针对RAND()的提示大概意思就是,在 ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描,导致效率相当相当的低,效率不行,切..

多语言网站数据库文章表设计

设计一个支持多语言的网站数据库时,应该确保内容能够方便地扩展和管理。以下是多语言数据库表设计的关键原则和示例:设计原则分离内容与语言:将与语言相关的内容独立存储,不直接硬编码到主要表中。每个支持多语言..

C#13新特性 使用System.Threading.Lock简化线程同步

C# 13 引入了新的线程同步类型 System.Threading.Lock,它通过作用域管理的方式简化了锁的使用,使代码更加清晰可靠。本文将全面介绍 System.Threading.Lock 的功能、适用场景,并提供完整的运行示例程序。1. 什么是..

ASP.NET 使用Entity Framework (EF) 创建迁移修改SQLite数据库表结构

在 ASP.NET 中,使用 Entity Framework (EF) 创建并连接 SQLite 数据库是一种轻量级、高效的数据库管理方式。以下是详细步骤:安装必要的 NuGet 包安装EntityFrameworkCore.Sqlite包:Install-Package Microsoft.Ent..

Mysql查询一段时间内的数据

select * from wap_content where week(created_at) = week(now)如果你要严格要求是某一年的,那可以这样查询一天:select * from table where to_days(column_time) = to_days(now());select * from table where da..

SQLite性能支持多少数据量?

SQLite是一种轻量级的关系型数据库管理系统,广泛应用于移动应用、嵌入式系统和小型桌面应用程序中。由于其零配置、自给自足的特性,SQLite在很多场景下非常受欢迎。然而,对于许多开发者来说,一个常见的问题是:SQ..

Sylvan.Data.Excel 性能优异的开源.NET Excel数据读取库

Sylvan.Data.Excel是一个开源、免费、跨平台的.NET库,专注于读取和写入Excel数据文件。支持多种文件格式,并提供高效的数据访问和数据绑定功能。该库在.NET生态系统中是读取Excel数据文件的最快且内存分配最低的库..

.NET9 F#有什么新特性?

F# 9 的新特性简介F# 9 是 .NET 9 的一部分,带来了多项增强功能,旨在提升开发效率和语言特性的一致性。这些改进不仅为现有的 F# 开发者提供了更强大的工具,也使新手更容易上手。以下是主要特性概览:1. 改进的类..

.NET9 C# 13 有哪些新特性?

在 .NET 9 和 C# 13 中,微软引入了一些新的语言特性和性能改进,帮助开发者提高代码效率、简化语法和提升可维护性。以下是一些主要的新特性:参数扩展支持:params 参数现在可以支持除数组外的集合类型,例如 List..

HTQL 提取和查询HTML和XML数据的轻量级查询语言

HTQL(Hyper-Text Query Language)是一种用于提取和查询HTML和XML数据的轻量级查询语言。HTQL提供类似SQL的语法,可以方便地从网页或其他基于标签的文档中提取结构化数据,而无需解析整个文档。这使得它在爬虫、数..

使用ADO.NET连接到南大通用GBase 8s数据库

南大通用GBase 8s数据库广泛应用于各种企业级应用中,对于开发者而言,掌握如何使用ADO.NET连接到GBase 8s数据库非常重要。本文将详细阐述如何通过ADO.NET方式连接到南大通用GBase 8s数据库,并进行基本的数据库操作..

MySQL 5.x和MySQL 8.x数据库的区别

MySQL 是开源关系型数据库的代表,广泛应用于不同规模的 Web 和企业应用中。从 MySQL 5.x 到 MySQL 8.x 的升级带来了大量功能改进和性能提升。为了帮助大家更直观地理解两者的区别,本文将通过详细介绍并结合实际的 ..

Redis 同步、击穿、穿透及雪崩简述

对Redis最常见的几个问题,简要的说下我的理解与解决方法。数据同步指Redis做为缓存,在数据变化时,怎么保持与数据库数据同步的。一般解决方案为:缓存双删(同步方案大都采用删除缓存,而不会更新新缓存。缓存击穿..

Vue 3.5引入新特性 还有与SSR相关的改进

Vue 3.5引入了响应式属性解构、useTemplateRef方法、useId实用函数、内部响应性重构等新特性。以下是具体介绍:响应式属性解构此功能允许开发者在defineProps宏中解构属性而不会失去响应性,这为组件间的属性传递提..

发表回复

返回顶部