数据校验

简介:

校验介绍

一个应用的输入应该首先要验证。这个输入可以是用户的输入,也可以是另一个应用的输入。在一个Web应用中,验证通常要实现2次:第一次是客户端验证,第二次是服务端验证。客户端的验证是为了更好的用户体验,通过检测表单的字段来提醒用户必须的字段;服务端的验证是更严格且无法避免的。

服务端的验证是在应用服务层实现的。应用服务方法应该首先检查(验证)输入然后在使用。ABP提供了一个不错的基础设施来验证应用服务方法的输入。

输入服务方法以一个DTO对象作为输入参数。ABP提供了一个DTO可以实现的IValidate接口来自动验证它们。因为IInputDto扩展了IValidate,因此输入DTOs可以只实现IInput来确保验证。

使用数据注解

ABP支持数据注解,ABP通过MethodInvocationValidator对服务层方法参数拦截,需要实现验证的方法,使用ValidationInterceptor进行拦截。对应的源码在 Abp.Runtime.Validation.Interception命名空间。

现在我在CityInput文件中添加一个类CreateCityInput,代码如下:

复制代码
public class CreateCityInput : IInputDto, IShouldNormalize
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Code { get; set; }
    [Required]
    public string ProvinceCode { get; set; }
    public DateTime UpdatedTime { get; set; }
    public string UpdatedBy { get; set; }

    public void Normalize()
    {
        if (UpdatedTime==null)
        {
            UpdatedTime=DateTime.Now;
        }
    }
}
复制代码

CreateCityInput类实现了IInput和IShouldNormalize接口,并且在Name,Code,ProvinceCode是必填字段,最后实现了IShouldNormalize接口中的Normalize方法,判断了UpdatedTime是否为null,如果是null,就赋值为当前的时间。

在ICityAppService服务接口中添加方法:

void CreateCity(CreateCityInput input);

在CityAppService中实现该接口的此方法:

复制代码
public void CreateCity(CreateCityInput input)
{
    var city = _cityRepository.FirstOrDefault(c => c.Name == input.Name);
    if (city != null)
    {
        throw new UserFriendlyException("该城市数据已经存在!");
    }
    city = new Cities() { Code = input.Code, Name = input.Name, ProvinceCode = input.ProvinceCode };
    _cityRepository.Insert(city);
}
复制代码

在CityController中添加Create方法:

复制代码
public ActionResult Create()
{
    var input = new CreateCityInput()
    {
        Name = "温州",
        ProvinceCode = "1",
        Code = "3",
    };
    _cityAppService.CreateCity(input);
    return Content("OK");
}
复制代码

这里,我们创建了一个CreateCityInput对象,并给三个必填字段赋值,然后调用服务接口的方法,如果服务方法执行成功,就向页面返回OK。

image

image

方法执行成功,数据库中也成功添加了数据。

现在我们不给这三个必填字段之一赋值,修改CityController代码如下:

复制代码
public ActionResult Create()
{
    var input = new CreateCityInput()
    {
        Name = "台州",
        //ProvinceCode = "1",
        Code = "3",
    };
    _cityAppService.CreateCity(input);
    return Content("OK");
}
复制代码

image

结果报错了,错误是“方法实参无效!请看验证错误细节。”可见,添加数据注解的属性因为不符合条件而产生的错误被成功拦截。ABP也会检测输入是否为null,如果为null,就抛出AbpValidationException异常。因此,不必写检测null的代码。如果输入的属性之一是无效的,也会抛出相同的异常。

这种机制和ASP.NET MVC的验证机制很相似,但是注意应用服务类不是派生自Controller类的,它是一个普通的类并且可以独立于web工作。

自定义验证

如果数据注解还不能满足你的需求的话,你也可以实现ICustomValidate接口:

复制代码
public class CreateCityInput : IInputDto, IShouldNormalize,ICustomValidate
{
    [Required]
    public string Name { get; set; }
    [Required]
    public string Code { get; set; }
    [Required]
    public string ProvinceCode { get; set; }
    public DateTime UpdatedTime { get; set; }
    public string UpdatedBy { get; set; }

    public void Normalize()
    {
        if (UpdatedTime==null)
        {
            UpdatedTime=DateTime.Now;
        }
    }

    public void AddValidationErrors(List<ValidationResult> results)
    {
        if (ProvinceCode.Length>5)
        {
            results.Add(new ValidationResult("省份编码长度不能超过5个字符!"));
            throw new Exception("省份编码长度不能超过5个字符!");
        }
    }
}
复制代码
复制代码
public ActionResult Create()
{
    var input = new CreateCityInput()
    {
        Name = "衢州",
        ProvinceCode = "123456",
        Code = "4",
    };
    _cityAppService.CreateCity(input);
    return Content("OK");
}
复制代码

这里代码很简单,不用多做解释,(有问题的话直接评论区提问),直接测试一下。

image

 

标准化

标准化就是在验证之后,进行一些额外的操作。其实前面的代码已经标准化了,ABP定义了一个

具有Normalize方法的IShouldNormalize接口。如果实现了这个接口,Normalize方法就会在验证之后调用。正如之前的示例代码:

复制代码
public void Normalize()
{
    if (UpdatedTime==null)
    {
        UpdatedTime=DateTime.Now;
    }
}
复制代码

这个作用就是,数据验证之后,如果UpdatedTime属性值为null,那么就把当前时间给它。当然,客户端传过来的数据也可能给UpdatedTime赋值,这样Normalize方法就不会执行了。






本文转自tkbSimplest博客园博客,原文链接:http://www.cnblogs.com/farb/p/4936961.html,如需转载请自行联系原作者

目录
相关文章
|
3月前
|
传感器 安全 前端开发
USB专用过压保护ic芯片选型指南
平芯微电子推出高性能过压过流保护芯片系列,涵盖OVP/OCP双重防护、超低内阻、宽压可调等创新技术,提供从消费电子到车载系统的全场景电源保护方案,助力提升产品可靠性与竞争力。
|
Java
手动将多个Jar包合并成1个Jar包
手动将多个Jar包合并成1个Jar包
572 0
|
监控 安全 Cloud Native
容器安全的风险应对及 Twislock 容器安全方案| 学习笔记
快速学习容器安全的风险应对及 Twislock 容器安全方案。
容器安全的风险应对及 Twislock 容器安全方案| 学习笔记
|
6月前
|
XML 安全 API
VMware Aria Operations 8.18.5 发布,新增功能概览
VMware Aria Operations 8.18.5 发布,新增功能概览
347 46
VMware Aria Operations 8.18.5 发布,新增功能概览
|
9月前
|
存储 SQL Apache
网易云信 x Doris:降本70%、提速11倍, 统一 ES/InfluxDB/Hive 多技术栈的落地实践
网易云信引入 Apache Doris 统一了原有 Elasticsearch、InfluxDB 和 Hive 多技术栈系统。凭借其高性能和易扩展的特点,提供一站式的数据存储和分析服务。实现机器成本降低 70%、实时场景查询提速 11 倍、离线任务耗时缩短 80% 的显著收益。
692 0
|
运维 监控 安全
IDS 和 IPS 日志监控的重要性
本文介绍了入侵检测系统(IDS)与入侵防御系统(IPS)在企业网络安全中的重要作用及区别。IDS通过监控网络流量、识别异常活动并生成警报,采用异常检测和签名检测等方法保障安全;而IPS作为自动化设备,主动分析流量并阻止恶意攻击,同时重新配置防火墙以增强防护能力。两者协同工作可实时抵御威胁,并通过日志记录和分析优化安全策略。此外,卓豪EventLog Analyzer能有效监控和分析IDS/IPS日志,助力企业精准识别复杂威胁,提升整体网络安全水平。
277 0
|
存储 并行计算 测试技术
NumPy 性能优化:提升 Python 数值计算的速度
【8月更文第30天】Python 是一种广泛使用的编程语言,在科学计算领域尤其受欢迎。然而,由于 Python 的动态类型和解释执行机制,其在处理大规模数值数据时可能会显得相对较慢。为了克服这一限制,NumPy(Numerical Python)库提供了高性能的多维数组对象以及一系列用于操作这些数组的函数。本文将探讨如何利用 NumPy 来提高 Python 中数值运算的效率。
1371 1
|
存储 分布式计算 NoSQL
HBase和Cassandra的分布式架构深度对比
HBase和Cassandra几乎都是一个时候出现的,都是在2010年成为Apache的顶级项目,不过如果我们细品其内部机制,我们会发现其实两者是完全不同的架构风格。HBASE起源于Google BigTable,几乎遵从了BigTable论文的大多数架构设计。Cassandra则是采纳了BigTable的数据模型,同时吸收了Amazon Dynamo的分布式设计。因此从存储结构模型的微观上看,HBASE和Cassandra在单点存储数据的机理是类似的,但是从分布式架构的宏观上看,两者则大相径庭。
HBase和Cassandra的分布式架构深度对比
|
存储 数据采集 数据处理
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南
793 12
|
消息中间件 数据采集 存储
Kafka常见问题总结
会不会丢消息? Offset 怎么保存? Consumer 重复消费问题怎么处理? 如何保证消息的顺序? 数据倾斜怎么处理? 一个 Topic 分配多少个 Partiton 合适以及修改 Partiton有哪些限制?