校驗介紹
一個應用的輸入應該首先要驗證。這個輸入可以是用戶的輸入,也可以是另一個應用的輸入。在一個Web應用中,驗證通常要實現2次:第一次是客戶端驗證,第二次是服務端驗證。客戶端的驗證是爲了更好的用戶體驗,通過檢測表單的字段來提醒用戶必須的字段;服務端的驗證是更嚴格且無法避免的。
服務端的驗證是在應用服務層實現的。應用服務方法應該首先檢查(驗證)輸入然後在使用。ABP提供了一個不錯的基礎設施來驗證應用服務方法的輸入。
基礎驗證
查看模板創建的dto中可以看見如下的內容,其中Required和StringLength都繼承於ValidationAttribute類,如果我們需要自定義這樣公用的驗證方式,也可以自己繼承這個類,並引用。
public class RoleDto : EntityDto<int>
{
[Required]
[StringLength(AbpRoleBase.MaxNameLength)]
public string Name { get; set; }
[Required]
[StringLength(AbpRoleBase.MaxDisplayNameLength)]
public string DisplayName { get; set; }
public string NormalizedName { get; set; }
[StringLength(Role.MaxDescriptionLength)]
public string Description { get; set; }
public bool IsStatic { get; set; }
public List<string> Permissions { get; set; }
}
我們自己定義的dto也可以直接使用如下:
public class UpdateNoteDto : EntityDto<int>
{
/// <summary>
/// 標題
/// </summary>
public string Title { get; set; }
/// <summary>
/// 內容
/// </summary>
[Required]
public string Content { get; set; }
/// <summary>
/// 上次修改時間
/// </summary>
public DateTime? LastModificationTime { get; set; }
}
測試一下,在Swagger UI 中:
自定義驗證
對於特殊的邏輯,我們只在這個功能中驗證數據,別的地方用不到,我們也可以實現ICustomValidate接口類自定義驗證:
public class PublicNoteDto: UpdateNoteDto,ICustomValidate
{
/// <summary>
/// 簡單描述,用於微信推送時的描述或者其他
/// </summary>
public string Des { get; set; }
/// <summary>
/// 封面圖片,可用於微信推送時或者其他
/// </summary>
[Required]
public string Img { get; set; }
/// <summary>
/// 關鍵字,可用於搜索,分類等
/// </summary>
public string Tags { get; set; }
/// <summary>
/// 是否發佈
/// </summary>
public bool IsPublic { get; set; }
public void AddValidationErrors(CustomValidationContext context)
{
if (string.IsNullOrEmpty(Des))
{
string error = "描述不能爲空!";
context.Results.Add(new ValidationResult(error));
}
if (Des.Length < 10)
{
string error = "描述不能少於10個字!";
context.Results.Add(new ValidationResult(error));
}
if (Des.Length > 200)
{
string error = "描述不能大於200個字!";
context.Results.Add(new ValidationResult(error));
}
}
}
標準化
標準化就是在驗證之後,進行一些額外的操作。
具有Normalize方法的IShouldNormalize接口。如果實現了這個接口,Normalize方法就會在驗證之後調用。
public class CreateNoteDto : IShouldNormalize
{
/// <summary>
/// 創建時間
/// </summary>
public DateTime? CreationTime { get; set; }
/// <summary>
/// 創建人
/// </summary>
public long CreatorUserId { get; set; }
/// <summary>
/// 內容的數據類型 markdown內容,html內容,或者其他
/// </summary>
public int TextType { get; set; }
public void Normalize()
{
CreationTime = DateTime.Now;
}
}