热线(9:00-18:00):13544706711
当前位置: 首页 > 教程技巧 > 

[Web API] Web API 2 深入系列(7) Model绑定(下)

时间: 2016/10/30 13:04:06

文档目录


 


本节内容:



 


简介


一个应用的输入应当先要验证,这个输入可能来自用户或另一个应用,在一个web应用里,验证通常实现两次:在客户端和在服务端,客户端验证是为了用户体验,最好是先检查一个表单并向用户显示无效的输入,但是服务端的验证更具有决定性意义和必要性。


服务端验证通常实现在应用服务或控制器(通常,所有服务从展现层获取数据)。一个应用服务应该先检查(验证)输入然后再使用它。ABP提供了一个基础构造,自动验证一个应用的如下三个的所有输入:



如果需要禁用验证,请查看“禁用验证”小节。


 


使用数据注解


ABP支持数据注解特性,假设我们正在开发一个Task应用服务,它用来创建一个Task并需要一个输入,如下所示:



public class CreateTaskInput
{
public int? AssignedPersonId { get; set; }

[Required]
public string Description { get; set; }
}


这里的Description属性被标记为Required,AssingedPersonId是可选的,在System.ComponentModel.DataAnnotations命名空间里,还有很多特性(如MaxLength、MinLenggth、RegularExpression...)。下面为Task应用服务的实现:



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);
}
}


就像你看到的,没有写验证代码,因为ABP自动完成验证。ABP会验证如果输入为null,就抛出AbpValidationException,所以你不需要写null检查。如果输入的任何属性是无效的,它也会抛出AbpValidationException。


这种机制类似于Asp.net Mvc的验证,但请注意一个应用服务类不是从控制器继承过来,它就是一个单纯的类,甚至可以在一个web应用以外使用该类。


 


自定义验证


如果数据注解不够你用,你可以实现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接口定义了AddValidationErrors方法,如果有验证错误,我们必须添加ValidationResult对象到context.Results列表。在验证进度里,如果有需要,你可以用context.IocResolver来解析依赖


除了ICustomValidate,ABP也支持IValidatableObject接口。你同样也可以实现它,执行额外的自定义验证。如果你同时实现了这两个接口,这两个都会被调用。


 


禁用验证


对于自动验证类(查看“简介”小节),你可以使用这些特性来控制验证:



  • DisableValidation特性:可用在DTO的类,方法或属性上来禁用验证。

  • EnableValidation特性:在一个被禁用验证的类里,可以在方法上使用这个特性让当前方法的输入验证可用。


 


正常化


有时我们需要在验证后,执行一个额外的操作来整理DTO参数。ABP定义了IShouldNormailize接口,包含Normalize方法,如果你实现了这个接口,Normalize方法在验证后(在方法被调用前)被调用。假设我们需要从DTO里取得排序方向(升序、降序),如果未提供,我们想设置一个默认值:



public class GetTasksInput : IShouldNormalize
{
public string Sorting { get; set; }

public void Normalize()
{
if (string.IsNullOrWhiteSpace(Sorting))
{
Sorting
= "Name ASC"
;
}
}

}