昨天給大家介紹了實體FluentValidation驗證,今天繼續給大家介紹表單驗證,在Rookey.Frame框架中,表單驗證有PrimaryKeyFields欄位驗證、唯一驗證、必填驗證、常用驗證及自定義驗證,PrimaryKeyFields欄位驗證昨天也略微介紹了下PrimaryKeyFiel ...
昨天給大家介紹了實體FluentValidation驗證,今天繼續給大家介紹表單驗證,在Rookey.Frame框架中,表單驗證有PrimaryKeyFields欄位驗證、唯一驗證、必填驗證、常用驗證及自定義驗證,PrimaryKeyFields欄位驗證昨天也略微介紹了下PrimaryKeyFields對記錄唯一性進行驗證,也即是由定義的一個或多個欄位唯一確定一條記錄,保存時不允許重覆,根據定義的,就是在實體表定義時在[ModuleConfig]實體類屬性標記中定義,也可以在模塊管理界面修改
針對唯一性驗證,可以在實體類屬性欄位標記[FieldConfig(IsUnique = true, IsRequired = true)]中定義,也可以在表單管理中修改
必填驗證同理。
針對常用驗證功能只能在表單中配置,打開表單管理在表單欄位中修改驗證類型:
目前支持的常用驗證類型見如下枚舉定義:
/// <summary> /// 驗證類型 /// </summary> public enum ValidateTypeEnum { /// <summary> /// 無 /// </summary> [Description("無")] No = 0, /// <summary> /// Eamil /// </summary> [Description("郵箱")] email = 1, /// <summary> /// URL /// </summary> [Description("網址")] url = 2, /// <summary> /// 整型 /// </summary> [Description("整型")] intNum = 3, /// <summary> /// 浮點型 /// </summary> [Description("浮點型")] floatNum = 4, /// <summary> /// 手機號碼 /// </summary> [Description("手機")] mobile = 5, /// <summary> /// QQ /// </summary> [Description("QQ")] qq = 6, /// <summary> /// 郵政編碼 /// </summary> [Description("郵政編碼")] zip = 7, /// <summary> /// 電話號碼 /// </summary> [Description("電話")] phone = 8, /// <summary> /// 傳真 /// </summary> [Description("傳真")] faxno = 9, /// <summary> /// 身份證 /// </summary> [Description("身份證")] idCard = 10 }
針對自身項目需要也可以將其他驗證添加到其中
另外表單驗證中針對數值型還可以設置最大最小值驗證,針對欄位串欄位可以設置最大最小字元長度驗證,同樣在在表單欄位中設置
表單驗證代碼如下:
/// <summary> /// 表單欄位配置驗證 /// </summary> /// <param name="moduleId">模塊Id</param> /// <param name="model">實體對象</param> /// <param name="verifyFields">需要驗證欄位的欄位集合</param> /// <returns></returns> public static string FormFieldVerify(Guid moduleId, object model, List<string> verifyFields) { Type modelType = GetModelType(moduleId); PropertyInfo idProperty = modelType.GetProperty("Id"); Guid id = idProperty.GetValue(model, null).ObjToGuid(); //當前記錄Id //表單欄位驗證 if (verifyFields != null && verifyFields.Count > 0) { foreach (string field in verifyFields) { PropertyInfo p = modelType.GetProperty(field); if (p == null) continue; object value = p.GetValue(model, null); Sys_FormField formField = SystemOperate.GetDefaultFormSingleField(moduleId, field); if (formField == null) continue; string fieldDisplay = SystemOperate.GetFieldDisplay(moduleId, field); #region 必填驗證 if (formField.IsRequired.HasValue && formField.IsRequired.Value) //必填驗證 { ControlTypeEnum crlType = formField.ControlTypeOfEnum; string requiredDes = crlType == ControlTypeEnum.ComboBox || crlType == ControlTypeEnum.ComboGrid || crlType == ControlTypeEnum.ComboTree ? "請選擇" : "不能為空"; bool isForeignField = SystemOperate.IsForeignField(moduleId, field); //是否是外鍵欄位 if (value == null || (isForeignField && value.ObjToGuid() == Guid.Empty)) { return string.Format("【{0}】為必填欄位,{1}!", fieldDisplay, requiredDes); } } if (formField.ControlTypeOfEnum == ControlTypeEnum.IntegerBox || formField.ControlTypeOfEnum == ControlTypeEnum.NumberBox) //最大值、最小值驗證 { if (formField.MinValue.HasValue && value.ObjToDecimal() < formField.MinValue.Value || formField.MaxValue.HasValue && value.ObjToDecimal() > formField.MaxValue.Value) { return string.Format("【{0}】的值介於【{1}】~【{2}】之間!", fieldDisplay, formField.MinValue.Value, formField.MaxValue.Value); } } if (p.PropertyType == typeof(String) && ((formField.MinCharLen.HasValue && formField.MinCharLen.Value > 0) || (formField.MaxCharLen.HasValue && formField.MaxCharLen.Value > 0))) //字元長度驗證 { if (value.ObjToStr().Length < formField.MinCharLen.Value || value.ObjToStr().Length > formField.MaxCharLen.Value) { return string.Format("【{0}】字元長度在【{1}】~【{2}】之間!", fieldDisplay, formField.MinCharLen.Value, formField.MaxCharLen.Value); } } #endregion #region 基本驗證 if (formField.ValidateTypeOfEnum != ValidateTypeEnum.No && p.PropertyType == typeof(String)) { //基本驗證 switch (formField.ValidateTypeOfEnum) { case ValidateTypeEnum.email: { bool rs = Validator.IsEmail(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的郵箱地址!", fieldDisplay); } break; case ValidateTypeEnum.idCard: //身份證驗證 { bool rs = Validator.IsIDCard(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的身份證號碼!", fieldDisplay); } break; case ValidateTypeEnum.intNum: { bool rs = Validator.IsInteger(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,只能輸入整數值!", fieldDisplay); } break; case ValidateTypeEnum.floatNum: { bool rs = Validator.IsNumber(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,只能輸入數值!", fieldDisplay); } break; case ValidateTypeEnum.faxno: case ValidateTypeEnum.phone: { bool rs = Validator.IsTelePhoneNumber(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的固定電話號碼!", fieldDisplay); } break; case ValidateTypeEnum.mobile: { bool rs = Validator.IsMobilePhoneNumber(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的手機號碼!", fieldDisplay); } break; case ValidateTypeEnum.qq: { bool rs = Validator.IsIntegerPositive(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的QQ號碼!", fieldDisplay); } break; case ValidateTypeEnum.url: { bool rs = Validator.IsURL(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的URL!", fieldDisplay); } break; case ValidateTypeEnum.zip: { bool rs = Validator.IsZipCode(value.ObjToStr()); if (!rs) return string.Format("【{0}】欄位值無效,請輸入正確的郵編!", fieldDisplay); } break; } } #endregion #region 欄位唯一性驗證 if (formField.IsUnique.HasValue && formField.IsUnique.Value) //唯一性驗證 { List<ConditionItem> conditonItems = new List<ConditionItem>() { new ConditionItem() { Field = field, Method = QueryMethod.Equal, Value = value } }; if (id != Guid.Empty) //編輯時排除當前記錄 { conditonItems.Add(new ConditionItem() { Field = "Id", Method = QueryMethod.NotEqual, Value = id }); } object exp = GetQueryCondition(moduleId, conditonItems); string errMsg = string.Empty; object tempModel = GetEntity(moduleId, exp, null, out errMsg); if (tempModel != null) { return string.Format("【{0}】=【{1}】的記錄已存在,請不要重覆添加!", fieldDisplay, SystemOperate.GetFieldDisplayValue(moduleId, model, formField)); } } #endregion } } return string.Empty; }
針對自定義驗證,框架提供了驗證介面
/// <summary> /// 操作處理介面 /// </summary> /// <typeparam name="T"></typeparam> public interface IModelOperateHandle<T> where T : class {/// <summary> /// 單個實體操作前驗證或處理,針對新增保存前、刪除前、修改保存前 /// </summary> /// <param name="operateType">操作類型</param> /// <param name="t">操作對象</param> /// <param name="errMsg">錯誤信息</param> /// <param name="otherParams">其他參數</param> /// <returns>是否通過驗證</returns> bool BeforeOperateVerifyOrHandle(ModelRecordOperateType operateType, T t, out string errMsg, object[] otherParams = null);
/// <summary> /// 多個實體操作前驗證或處理,針對新增保存前、刪除前、修改保存前 /// </summary> /// <param name="operateType">操作類型</param> /// <param name="ts">操作對象集合</param> /// <param name="errMsg">錯誤信息</param> /// <param name="otherParams">其他參數</param> /// <returns>是否通過驗證</returns> bool BeforeOperateVerifyOrHandles(ModelRecordOperateType operateType, List<T> ts, out string errMsg, object[] otherParams = null); #endregion }
例如針對工作流程刪除驗證:
class Bpm_WorkFlowOperateHandle : IModelOperateHandle<Bpm_WorkFlow> {/// <summary> /// 操作前驗證,如果流程已經在運行則不能刪除 /// </summary> /// <param name="operateType"></param> /// <param name="t"></param> /// <param name="errMsg"></param> /// <param name="otherParams"></param> /// <returns></returns> public bool BeforeOperateVerifyOrHandle(ModelRecordOperateType operateType, Bpm_WorkFlow t, out string errMsg, object[] otherParams = null) { errMsg = string.Empty; if (operateType == ModelRecordOperateType.Del) { //如果該流程存在流程實例則不允許刪除 Bpm_WorkFlowInstance workflowInst = CommonOperate.GetEntity<Bpm_WorkFlowInstance>(x => x.Bpm_WorkFlowId == t.Id, null, out errMsg); if (workflowInst != null) { errMsg = "運行中的流程不允許刪除!"; return false; } } return true; } /// <summary> /// 操作前驗證 /// </summary> /// <param name="operateType"></param> /// <param name="ts"></param> /// <param name="errMsg"></param> /// <param name="otherParams"></param> /// <returns></returns> public bool BeforeOperateVerifyOrHandles(ModelRecordOperateType operateType, List<Bpm_WorkFlow> ts, out string errMsg, object[] otherParams = null) { errMsg = string.Empty; if (operateType == ModelRecordOperateType.Del) { foreach (Bpm_WorkFlow t in ts) { //如果該流程存在流程實例則不允許刪除 Bpm_WorkFlowInstance workflowInst = CommonOperate.GetEntity<Bpm_WorkFlowInstance>(x => x.Bpm_WorkFlowId == t.Id, null, out errMsg); if (workflowInst != null) { errMsg += string.Format("【{0}】,", t.Name); } } if (errMsg.Length > 0) { errMsg = string.Format("流程{0}正在運行不允許刪除!", errMsg); return false; } } return true; } }
OK,由於時間有限今天Rookey.Frame框架驗證功能就介紹到此地,祝大家生活愉快!