首页 > 其他分享 >.NET中特性+反射 实现数据校验

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

时间:2024-05-21 13:41:27浏览次数:16  
标签:反射 string errorMessage 校验 特性 NET public 属性

.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等框架结合使用。
使用这些特性可以大大简化数据验证的代码,并且使验证逻辑与业务逻辑分离,提高代码的可维护性和可读性。

标签:反射,string,errorMessage,校验,特性,NET,public,属性
From: https://www.cnblogs.com/cqai/p/18203814

相关文章

  • .net 4.8 webApi 文件下载部分代码记录
    privateHttpResponseMessageExportData(stringids,Func<string,string>exportFunc,stringdataNotExistsMsg){varfilePath=exportFunc.Invoke(ids);//检查文件是否存在if(!File.Exists(filePath)){......
  • .net8 winform程序使用EntityFrameworkCore连接数据库
    在.NET8WinForms应用程序中使用EntityFramework(EF)Core,你需要按照以下步骤操作:1.添加EntityFrameworkCoreNuGet包。2.定义你的数据模型。3.创建数据库上下文(DbContext)。4.在数据库上下文中配置EntityFramework。5.使用EntityFrameworkCore的API来执行数据库操作。......
  • dotnet 命令行工具解决方案 PomeloCli
    目录PomeloCli是什么为什么实现太多的工具太少的规范基于二进制拷贝分发难以为继快速开始1.引用PomeloCli开发命令行应用2.引用PomeloCli开发命令行插件开发命令行插件搭建私有nuget服务发布命令行插件3.使用PomeloCli集成已发布插件安装命令行宿主集成命令行插件卸......
  • .NET 中的表达式树
    .NET中的表达式树(ExpressionTrees)表达式树是什么?表达式树(ExpressionTrees)是.NET框架中的一个强大功能,它将代码表示为一个由表达式节点组成的树形结构。每个节点代表代码中的一个操作,例如方法调用、算术运算、逻辑运算等。表达式树允许开发者在运行时分析、修改和执行代码。......
  • EDP .Net开发框架--WebApi
    平台下载地址:https://gitee.com/alwaysinsist/edp按分类管理EDP所提供的WebApi接口,以供其他应用调用。WebApi接口不仅可以进行访问控制管理,同时还提供了版本管理,同一WebApi接口支持多个不同版本以满足接口调用方的多版本支持。WebApi接口的数据是通过调用业务方法来获取的,而业......
  • skynet框架:单点服务性能优化思路
    skynet框架下的业务开发,单点服务是存在理论瓶颈的。当业务上存在并发请求的场景时,服务会成为性能热点,达到服务的消费瓶颈,出现过载。原则上讨论,当业务需求一个执行单位成为并发热点,那么实现这个执行单位就需要是足够支撑业务上限的方案。基于这个思路,讨论几个优化:解耦;降低过载......
  • .NET 中的表达式树
    .NET中的表达式树(ExpressionTrees)表达式树是什么?表达式树(ExpressionTrees)是.NET框架中的一个强大功能,它将代码表示为一个由表达式节点组成的树形结构。每个节点代表代码中的一个操作,例如方法调用、算术运算、逻辑运算等。表达式树允许开发者在运行时分析、修改和执行代码。......
  • Java手机号校验规则最新
    一、最新的Java手机号校验规则在Java中,进行手机号校验通常使用正则表达式(Regex)来匹配手机号的格式。以下是一个基于当前(截至2024年)中国手机号规则的校验方法:中国手机号通常以数字1开头,第二位在3、4、5、7、8、9中选择,后面跟着9位数字,总共11位。以下是一个使用正则表达式实现手机......
  • Liunx部署NetCore,接口获取mysql本地数据时报:The SSL connection could not be establ
    今天将 NETCore程序发布到一台新的服务器,程序中有https请求第三方的Api,但是报了如下的错误:TheSSLconnectioncouldnotbeestablished,seeinnerexception解决办法下面命令查询openssl的路径opensslversion-a然后将CentOS默认的opensslCA证书拷贝到OPENSSLD......
  • netcore6 发布到linux centos7 踩坑记录
    具体dotnet6部署的过程,用守护进程。参考:https://blog.csdn.net/qq_45602658/article/details/129299814还有解决出现dotnet:/lib64/libstdc++.so.6:versionGLIBCXX_3.4.21&#x27;notfound(requiredbydotnet)dotnet:/lib64/libstdc++.so.6:未找到版本GLIBCXX_3.4.21(dot......