WebApi資料驗證——編寫自定義資料註解(Data Annotations)
配合ModelState使用,關於使用方法,參考微軟文件
自定義Data Annotations只需要繼承ValidationAttribute,並且重寫IsValid方法。
示例:
// =================================================================== // ModelState自定義註解 // 多個欄位分組判斷,全部不允許為空或至少有一個不為空 //==================================================================== // CreateTime:2019-04-24 // Author:liucx // =================================================================== using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OF.Component.Model { /// <summary> /// 多個屬性欄位分組不為空判斷 傳入引數逗號間隔 /// <example>[GroupEmpty("p1,p2,p3",false,ErrorMessage="p1p2p3三個引數中至少有一個非空")] </example> /// </summary> public class GroupEmptyAttribute : ValidationAttribute { private readonly string _groupFields; private readonly bool _notNullableAll; /// <summary> /// 建構函式 /// </summary> /// <param name="groupFields">屬性名,多個屬性名逗號隔開</param> /// <param name="notNullableAll"> true全部不允許為空。 false只要存在不為空的屬性即可</param> public GroupEmptyAttribute(string groupFields, bool notNullableAll) { _groupFields = groupFields; _notNullableAll = notNullableAll; } /// <summary> /// 建構函式,預設至少1個非空 /// </summary> /// <param name="groupFields">屬性名,多個屬性名逗號隔開</param> public GroupEmptyAttribute(string groupFields) { _groupFields = groupFields; _notNullableAll = false; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var validateResult = false; var obj = validationContext.ObjectInstance; Type Ts = obj.GetType(); var fields = _groupFields.Split(','); if (fields.Count() > 0) { for (var i = 0; i < fields.Count(); i++) { var filedName = Convert.ToString(fields[i]); if (string.IsNullOrEmpty(filedName)) continue; //value string filedValue = Convert.ToString(Ts.GetProperty(filedName).GetValue(obj, null)); //_notNullableAll=true,任意一個為空直接驗證掛掉跳出迴圈 if (_notNullableAll && string.IsNullOrWhiteSpace(filedValue)) { validateResult = false; break; } //_notNullableAll=false,只要有一個不為空就可以過驗證 if (!_notNullableAll && !string.IsNullOrWhiteSpace(filedValue)) { validateResult = true; break; } } } //success if (validateResult) return ValidationResult.Success; else { //fail if (string.IsNullOrEmpty(ErrorMessage) && _notNullableAll) return new ValidationResult($"{_groupFields}欄位全部不允許為空值"); else if (string.IsNullOrEmpty(ErrorMessage) && !_notNullableAll) return new ValidationResult($"{_groupFields}欄位中至少要有一個不為空的值"); else return new ValidationResult(ErrorMessage); } } } /// <summary> /// 組內資料同步判斷,同時為空或同時不為空通過驗證 /// </summary> public class GroupEmptySyncAttribute : ValidationAttribute { private readonly string _groupFields; public GroupEmptySyncAttribute(string groupFields) { _groupFields = groupFields; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var validateResult = true; var obj = validationContext.ObjectInstance; Type Ts = obj.GetType(); var fields = _groupFields.Split(','); if (fields.Count() > 0) { bool firstValueIsEmpty = true;//第一個值是否為空 for (var i = 0; i < fields.Count(); i++) { var filedName = Convert.ToString(fields[i]); if (string.IsNullOrEmpty(filedName)) continue; //value string filedValue = Convert.ToString(Ts.GetProperty(filedName).GetValue(obj, null)); //第一個值記錄是否為空 if (i == 0 && string.IsNullOrWhiteSpace(filedValue)) firstValueIsEmpty = true; if (i == 0 && !string.IsNullOrWhiteSpace(filedValue)) firstValueIsEmpty = false; //後續值判斷是否和第一個值符合,不符合直接結束驗證 if (i > 0) { if (string.IsNullOrWhiteSpace(filedValue) != firstValueIsEmpty) { validateResult = false; break; } } } } //success if (validateResult) return ValidationResult.Success; else { //fail if (string.IsNullOrEmpty(ErrorMessage)) return new ValidationResult($"{_groupFields}欄位是否為空不一致(必須同時為空或同時不為空)"); else return new ValidationResult(ErrorMessage); } } } /// <summary> /// 判斷時間格式是否對應,時間格式一致通過驗證 /// </summary> public class DateFormatValidAttribute : ValidationAttribute { private readonly string _formatStr; public DateFormatValidAttribute(string formatStr) { _formatStr = formatStr; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var validateResult = false; try { //轉成要求的格式後 再和傳入的值對比 var formatValue = Convert.ToDateTime((string)value).ToString(_formatStr); if ((string)value == formatValue) validateResult = true; else validateResult = false; //success if (validateResult) return ValidationResult.Success; else { //fail if (string.IsNullOrEmpty(ErrorMessage)) return new ValidationResult($"時間格式不符合{_formatStr}格式"); else return new ValidationResult(ErrorMessage); } } catch (Exception ex) { if (string.IsNullOrEmpty(ErrorMessage)) return new ValidationResult($"時間格式不符合{_formatStr}格式"); else return new ValidationResult(ErrorMessage); } } } }
使用:
測試結果:
相關推薦
WebApi資料驗證——編寫自定義資料註解(Data Annotations)
配合ModelState使用,關於使用方法,參考微軟文件 https://docs.microsoft.com/en-us/as
一句python,一句R︱列表、元組、字典、資料型別、自定義模組匯入(格式、去重)
先學了R,最近剛剛上手python,所以想著將python和R結合起來互相對比來更好理解python。最好就是一句python,對應寫一句R。pandas中有類似R中的read.table的功能,而且很像。———————————————————————————————————
自定義Java註解(annotation)
https://www.imooc.com/learn/456 筆記 Java從1.5開始引進註解。 首先解決一個問題,為什麼要學習Java註解? 1.看懂別人寫的程式碼,尤其是框架的程式碼 2.可以是自己寫的程式碼簡潔清晰 現在開始學習Java註解了。
ros編寫自定義的服務(.srv)
1、編寫自定義的服務檔案(即.srv)檔案。 2、儲存,catkin_make編譯,要生成可以被#include "包/AddTwoInts.h",注意CMakeList.txt檔案的配置 cmake_minimum_required(VERSION 2.8.3) project(le
Jasper Report之自定義組件(Custom Visualization)環境配置
win 進行 studio one component add 。。 版本 inf Jasper Report提供的功能已經足夠強大了,但是仍不能完全對接客戶的需求,因此需要我們自定義組件完成對我們Report的設計,開發前的環境配置還是個麻煩事。。。 系統:Linux I
vue中自定義組件(插件)
comment tty index all target mark cal ali lan vue中自定義組件(插件) 原創 2017年01月04日 22:46:43 標簽: 插件 在vue項目中,可以自定義組件像vue-resource一樣使用Vue.use(
Xamarin自定義佈局系列——ListView的一個自定義實現ItemsControl(橫向列表)
原文: Xamarin自定義佈局系列——ListView的一個自定義實現ItemsControl(橫向列表) 在以前寫UWP程式的時候,瞭解到在ListView或者ListBox這類的列表空間中,有一個叫做ItemsPannel的屬性,它是所有列表中子元素實際的容器,如果要讓列表進行橫向排列,只需要在Xam
VSCode 如何操作使用者自定義程式碼片段(快捷鍵)
如何操作使用者自定義程式碼片段(快捷鍵)? 第一步:檔案==>首選項==>使用者程式碼片段 第二步:選擇程式碼片段檔案 html.json 第三步:輸入要自定義的快捷鍵 和 模板程式碼段 { "vh": { "prefix
Django 框架中的自定義模板標籤(template.Library())
某一些標籤(例如:選單欄、css、JS、以及一些複雜計算後的資料等)需要我們自定義。 然後再在指定的html中引用並顯示。 之所以要用到標籤,主要作用就是想讓一些內容在多個模板(HTML)中都要有,比如選單欄。 我們絕對不想在每個檢視函式(views中)都寫一次這些變數內容。 即每個頁面
SpringBoot自定義配置檔案(xxx.properties)
轉載 :https://www.cnblogs.com/V1haoge/p/7183408.htmlSpringBoot中免除了大部分手動配置,但是對於一些特定的情況,還是需要我們進行手動配置的,SpringBoot為我們提供了application.properties配置檔案,讓我們可以進行自定義配置,來
Rabbit MQ 自定義監聽器容器(Listener Container)的啟動與停止
專案中會遇到,MQ佇列的監聽是在某一前提條件準備好的情況下才啟動,比如MQ接收到一系列資料,這些資料的儲存依賴於另外一個MQ訊息的一些配置接收之後才能完成。 指定屬性autoStartup為false,並啟動對應的listener id @RabbitHandl
spring-security 個性化使用者認證流程——自定義登入頁面(可配置)
1.定義自己的登入頁面我們需要根據自己的業務系統構建自己的登入頁面以及登入成功、失敗處理在spring security提供給我的登入頁面中,只有使用者名稱、密碼框,而自帶的登入成功頁面是空白頁面(可以重定向之前請求的路徑中),而登入失敗時也只是提示使用者被鎖定、過期等資訊。 在實際的開發中,則需要更
微信小程式之——自定義分享按鈕(完整版)
1.宣告 onShareAppMessage 函式 onShareAppMessage() { return { title: '彈出分享時顯示的分享標
自定義標籤庫(Tag library)
簡介 JSP標籤庫技術可以讓我們定製自己的標籤。 我們前邊講解了JSP動作標籤,動作標籤本質上就是一段Java程式碼,在JSP頁面被轉換為Servlet期間,JSP引擎解析到JSP檔案就會將動作標籤轉換為我們預先定義好的Java程式碼。 同樣,自定義標籤實際上一個實現了特定介面
配置RedisTemplate、JedisPoolConfig、JedisConnectionFactory+自定義序列化 (java方式)
java方式配置RedisTemplate //spring注入ben //@Bean(name = "redisTemplate") public RedisTemplate initRedisTemplate(){ JedisPoolConfig poolCo
自定義字典樹(字首樹)
通過學習自定義字典樹,瞭解字典樹這一資料結構。 之前的二分搜尋樹(二叉樹)、堆(完全二叉樹)、線段樹(平衡二叉樹)都是基於二叉樹。而字典樹是一種多叉樹。 如果有n個條目,使用樹結構查詢的時間複雜度為O(log n),如果有100
自定義線段樹(區間樹)
通過學習自定義線段樹(區間樹),瞭解線段樹這一資料結構。 線段樹首先是平衡二叉樹。 用例:查詢一個區間[i,j]的最大值,最小值,或者區間數字和等。 實質:基於區間的統計查詢。 為什麼用線段樹: 使用陣列
Qt之自定義控制元件(開關按鈕)
簡述 接觸過iOS系統的童鞋們應該對開關按鈕很熟悉,在設定裡面經常遇到,切換時候的滑動效果比較帥氣。 通常說的開關按鈕,有兩個狀態:on、off。 下面,我們利用自定義控制元件來實現一個開關按鈕。 原理 重寫滑鼠按下事件(mousePres
Android自定義View-TitleBar(標題欄)詳細說明
我們在開發Android介面時常常要在許多頁面中共用風格相似的標題欄,為了減少重複性工作我們可以將標題欄做成一個通用的自定義控制元件。 我將通過兩種形式的自定義方式介紹自定義TitleBar 第一種方式(不涉及自定義屬性) 首先通過在Layout中建一個佈局檔案先確定Ti
C# WinForm中如何自定義config檔案(XML檔案),並且讀取和儲存它
我這裡以連結資料庫為例子, 其中書寫的Config的xml檔案如下: <?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add k