傳回總目錄《一步一步使用ABP架構搭建正式項目系列教程》
校驗介紹
一個應用的輸入應該首先要驗證。這個輸入可以是使用者的輸入,也可以是另一個應用的輸入。在一個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。
方法執行成功,資料庫中也成功添加了資料。
現在我們不給這三個必填字段之一指派,修改CityController代碼如下:
public ActionResult Create()
{
var input = new CreateCityInput()
{
Name = "台州",
//ProvinceCode = "1",
Code = "3",
};
_cityAppService.CreateCity(input);
return Content("OK");
}
結果報錯了,錯誤是“方法實參無效!請看驗證錯誤細節。”可見,添加資料注解的屬性因為不符合條件而産生的錯誤被成功攔截。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");
}
這裡代碼很簡單,不用多做解釋,(有問題的話直接評論區提問),直接測試一下。
标準化
标準化就是在驗證之後,進行一些額外的操作。其實前面的代碼已經标準化了,ABP定義了一個
具有Normalize方法的IShouldNormalize接口。如果實作了這個接口,Normalize方法就會在驗證之後調用。正如之前的示例代碼:
public void Normalize()
{
if (UpdatedTime==null)
{
UpdatedTime=DateTime.Now;
}
}
這個作用就是,資料驗證之後,如果UpdatedTime屬性值為null,那麼就把目前時間給它。當然,用戶端傳過來的資料也可能給UpdatedTime指派,這樣Normalize方法就不會執行了。
如果您認為這篇文章還不錯或者有所收獲,您可以通過右邊的“打賞”功能 打賞我一杯咖啡【物質支援】,也可以點選右下角的【好文要頂】按鈕【精神支援】,因為這兩種支援都是我繼續寫作,分享的最大動力!
作者:tkb至簡
來源:http://farb.cnblogs.com/
聲明:原創部落格請在轉載時保留原文連結或者在文章開頭加上本人部落格位址,如發現錯誤,歡迎批評指正。凡是轉載于本人的文章,不能設定打賞功能,如有特殊需求請與本人聯系!
已将所有贊助者統一放到單獨頁面!簽名處隻保留最近10條贊助記錄!檢視贊助者清單
衷心感謝打賞者的厚愛與支援!也感謝點贊和評論的園友的支援! | ||
---|---|---|
打賞者 | 打賞金額 | 打賞日期 |
微信:匿名 | 10.00 | 2017-08-03 |
2017-08-04 | ||
5.00 | 2017-06-15 | |
支付寶:一個名字499***@qq.com | 2017-06-14 | |
16.00 | 2017-04-08 | |
支付寶:向京劉 | 2017-04-13 | |
2017-003-08 | ||
2017-03-08 | ||
支付寶:lll20001155 | 2017-03-03 | |
支付寶:她是一個弱女子 | 2017-03-02 |