ABP框架系列之五十二:(Validating-Data-Transfer-Objects-验证数据传输对象)
Introduction to validation
Inputs of an application should be validated first. This input can be sent by user or another application. In a web application, validation is usually implemented twice: in client and in the server. Client-side validation is implemented mostly for user experience. It's better to check a form first in the client and show invalid fields to the user. But, server-side validation is more critical and unavoidable.
应用程序的输入应该首先验证。此输入可以由用户或其他应用程序发送。在Web应用程序中,验证通常实现两次:客户端和服务器端。客户端验证主要用于用户体验。最好在客户端检查表单,并向用户显示无效字段。但是,服务器端验证更为关键和不可避免。
Server side validation is generally implemented in application services or controllers (in general, all services get data from presentation layer). An application service method should first check (validate) input and then use it. ASP.NET Boilerplate provides a good infrastructure to automatically validate all inputs of an application for;
服务器端验证通常在应用程序服务或控制器中实现(一般来说,所有服务都从表示层获取数据)。应用程序服务方法应该首先检查(验证)输入然后使用它。ASP.NET样板提供良好的基础设施来自动验证所有输入的应用;
- All application service methods
- All ASP.NET Core MVC controller actions
- All ASP.NET MVC and Web API controller actions.
See Disabling Validation section to disable validation if needed.
如果需要,请查看禁用验证部分禁用验证。
Using data annotations(使用数据注释)
ASP.NET Boilerplate supports data annotation attributes. Assume that we're developing a Task application service that is used to create a task and gets an input as shown below:
ASP.NET样板支持数据注解属性。假设我们正在开发一个任务应用程序服务,该服务用于创建任务并获取如下所示的输入:
public class CreateTaskInput
{
public int? AssignedPersonId { get; set; } [Required]
public string Description { get; set; }
}
Here, Description property is marked as Required. AssignedPersonId is optional. There are also many attributes (like MaxLength, MinLength, RegularExpression...) in System.ComponentModel.DataAnnotationsnamespace. See Task application service implementation:
这里,Description属性被标记为所需。assignedpersonid是可选的。也有许多属性(如MaxLength,minLength,正则表达式在System.ComponentModel.DataAnnotationsnamespace…)。查看任务应用程序服务实现:
public class TaskAppService : ITaskAppService
{
private readonly ITaskRepository _taskRepository;
private readonly IPersonRepository _personRepository; public TaskAppService(ITaskRepository taskRepository, IPersonRepository personRepository)
{
_taskRepository = taskRepository;
_personRepository = personRepository;
} public void CreateTask(CreateTaskInput input)
{
var task = new Task { Description = input.Description }; if (input.AssignedPersonId.HasValue)
{
task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);
} _taskRepository.Insert(task);
}
}
As you see, no validation code is written since ASP.NET Boilerplate does it automatically. ASP.NET Boilerplate also checks if input is null and throws AbpValidationException if so. So, you don't have to write null-check code (guard clause). It also throws AbpValidationException if any of the input properties are invalid.
正如你看到的,没有验证码可写,因为ASP.NET样板是自动写入的。ASP.NET样板检查是否输入是无效的,如果无效则抛出abpvalidationexception。因此,您不必编写null检查码(保护子句)。如果任何输入属性无效它会抛出abpvalidationexception。
This machanism is similar to ASP.NET MVC's validation but notice that an application service class is not derived from Controller, it's a plain class and can work even out of a web application.
这种机制是类似ASP.NET MVC的验证而注意到应用服务类不是来自控制器,它是一个普通班,甚至可以从一个Web应用程序的工作
Custom Validation(自定义验证)
If data annotations are not sufficient for your case, you can implement ICustomValidate interface as shown below:
如果数据注释不够满足你的情况,你可以实现icustomvalidate 接口如下图所示:
public class CreateTaskInput : ICustomValidate
{
public int? AssignedPersonId { get; set; } public bool SendEmailToAssignedPerson { get; set; } [Required]
public string Description { get; set; } public void AddValidationErrors(CustomValidatationContext context)
{
if (SendEmailToAssignedPerson && (!AssignedPersonId.HasValue || AssignedPersonId.Value <= 0))
{
context.Results.Add(new ValidationResult("AssignedPersonId must be set if SendEmailToAssignedPerson is true!"));
}
}
}
ICustomValidate interface declares AddValidationErrors method to be implemented. We must add ValidationResult objects to context.Results list if there are validation errors. You can also use context.IocResolver toresolve dependencies if needed in validation progress.
icustomvalidate 接口揭露 addvalidationerrors方法被执行。我们必须在上下文中加上ValidationResult对象。如果验证错误。你也可以使用context.iocresolver 如果在验证中需要。
In addition to ICustomValidate, ABP also supports .NET's standard IValidatableObject interface. You can also implement it to perform additional custom validations. If you implement both interfaces, both of them will be called.
除了icustomvalidate,ABP也支持.NET的标准ivalidatableobject接口。您也可以执行它执行其他自定义验证。如果实现这两个接口,它们都将被调用。
Disabling Validation(禁用验证)
For automatically validated classes (see Introduction section), you can use these attributes to control validation:
对于自动验证类(参见导言部分),您可以使用这些属性来控制验证:
- DisableValidation attribute can be used for classes, methods or properties of DTOs to disable validation.
- disablevalidation属性可以用于类、方法或属性的DTOS禁用验证。
- EnableValidation attribute can only be used to enable validation for a method, if it's disabled for the containing class.
- enablevalidation属性只能用于使一个方法验证,如果该类被禁用。
Normalization(标准化)
We may need to perform an extra operation to arrange DTO parameters after validation. ASP.NET Boilerplate defines IShouldNormalize interface that has Normalize method for that. If you implement this interface, Normalize method is called just after validation (and just before method call). Assume that our DTO gets a Sorting direction. If it's not supplied, we want to set a default sorting:
我们可能需要执行额外的操作安排DTO参数后验证。ASP.NET的模板定义ishouldnormalize接口,有规范的方法。如果实现此接口,则在验证之后(调用方法调用之前)调用标准化方法。假设我们的DTO获取排序方向。如果没有提供,我们要设置默认排序:
public class GetTasksInput : IShouldNormalize
{
public string Sorting { get; set; } public void Normalize()
{
if (string.IsNullOrWhiteSpace(Sorting))
{
Sorting = "Name ASC";
}
}
}
ABP框架系列之五十二:(Validating-Data-Transfer-Objects-验证数据传输对象)的更多相关文章
- ABP框架系列之五十四:(XSRF-CSRF-Protection-跨站请求伪造保护)
Introduction "Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a maliciou ...
- ABP框架系列之十二:(Audit-Logging-审计日志)
Introduction Wikipedia: "An audit trail (also called audit log) is a security-relevant chronolo ...
- ABP框架系列之三十二:(Logging-登录)
Server Side(服务端) ASP.NET Boilerplate uses Castle Windsor's logging facility. It can work with differ ...
- ABP框架系列之四十二:(Object-To-Object-Mapping-对象映射)
Introduction It's a common to map a similar object to another object. It's also tedious and repeatin ...
- ABP框架系列之五十:(Swagger-UI-集成)
Introduction From it's web site: "....with a Swagger-enabled API, you get interactive documenta ...
- ABP框架系列之三十九:(NLayer-Architecture-多层架构)
Introduction Layering of an application's codebase is a widely accepted technique to help reduce com ...
- ABP框架系列之十八:(Data-Transfer-Objects-数据转换对象)
Data Transfer Objects are used to transfer data between Application Layer and Presentation Layer. 数据 ...
- ABP框架系列之三十四:(Multi-Tenancy-多租户)
What Is Multi Tenancy? "Software Multitenancy refers to a software architecture in which a sing ...
- ABP框架系列之十:(Application-Services-应用服务)
Application Services are used to expose domain logic to the presentation layer. An Application Servi ...
随机推荐
- 使用jquery+css实现瀑布流布局
虽然可以直接使用css实现瀑布流布局,但显示的方式有点问题,所以这儿就直接使用jquery+css来实现瀑布流布局,最终效果如下: 思路是通过将每个小块的position设置为relativ ...
- Sklearn (一) 监督学习
本系列博文是根据SKlearn的一个学习小结,并非原创! 1.直接学习TensorFlow有点不知所措,感觉需要一些基础知识做铺垫. 2.之前机器学习都是理论<Ng机器学习基础>+底层 ...
- SpringMVC之DispatcherServlet类图
DispatcherServlet类图 在IntelliJ IDEA 中打开其源码,然后右键查看Diagrams,工具会自动生成其类图. 可是直观的看出,DispatcherServlet本质上是Se ...
- Android 开发 系统组件集合
常用的TextView.Button.ImageView和几个常用布局就不介绍了,我们介绍一些特别好用但是常常忘记的组件. 标题栏组件 <androidx.appcompat.widget.To ...
- leetcode每日刷题计划-简单篇day2
今天数模比赛爆肝&操作系统大作业 脖子疼orz先把题过了保证flag不倒..个别细节回头看吧 Num 13 罗马数字转整数 Roman to Integer 一遍提交过,开始编译出了点问题 具 ...
- easy ui 关闭选项卡
var tab = window.parent.getCurrentTab(); var tabs = window.parent.getTabs(); var index = tabs.tabs(& ...
- iOS app审核被拒申诉
提交申诉理由之后不需要点击“提交审核”按钮,否则按照重新提交算,需要重新排队,且申诉会不起作用.
- c++ 中的智能指针实现
摘要:C++11 中新增加了智能指针来预防内存泄漏的问题,在 share_ptr 中主要是通过“引用计数机制”来实现的.我们今天也来自己实现一个简单的智能指针: // smartPointer.cpp ...
- GitLab代码行数统计--统计增加与删除行数
#!/bin/bashmaster_dev='master'date_star='2018-11-01'date_end='2018-11-30'path1=`find /home/gitlab_da ...
- C++类有继承时,析构函数必须为虚函数
C++类有继承时,析构函数必须为虚函数.如果不是虚函数,则使用时可能存在内在泄漏的问题. 假设我们有这样一种继承关系: 如果我们以这种方式创建对象: SubClass* pObj = new SubC ...