当前位置: 首页 > 编程语言 > C#

使用ASP.NETMVC4在运行时动态应用验证规则分享

时间:2023-04-10 11:25:40 C#

使用ASP.NETMVC4在运行时动态应用验证规则new。我试图弄清楚如何在运行时将动态验证规则应用于我的模型成员。出于这个问题的目的,这些是我正在使用的类的简化版本:publicclassDevice{publicintId{get;设置;}公共ICollection设置{get;设置;}}公共类设置{公共intId{get;设置;}公共字符串值{get;设置;}publicboolIsRequired{get;设置;}公共intMinLength{得到;设置;}公共intMaxLength{得到;编辑器遍历Settings集合,并在运行时应用每个Setting实例中包含的验证规则,以在编译时使用模型上的DataAnnotations获得相同的客户端和服务器端验证。在WebForms中,我只是在相关字段上附上相应的Validator,但在MVC4中找不到类似的机制。有没有办法做到这一点?我的解决方案是扩展ValidationAttribute类并实现IClientValidatable接口。下面是一个完整的演示例子,有一些修改进入空间:usingSystem;使用System.Collections.Generic;使用System.ComponentModel.DataAnnotations;使用System.Reflection;使用System.Web.Mvc;命名空间WebApplication.Common{[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]publicclassRuntimeRequiredAttribute:ValidationAttribute,IClientValidatable{publicstringBooleanSwitch{get;私有集;}publicboolAllowEmptyStrings{得到;私有集;}publicRuntimeRequiredAttribute(stringbooleanSwitch="IsRequired",boolallowEmpytStrings=false):base("{0}字段是必需的。"){BooleanSwitch=booleanSwitch;AllowEmptyStrings=allowEmpytStrings;}protectedoverrideValidationResultIsValid(objectvalue,ValidationContextvalidationContext){PropertyInfoproperty=validationContext.ObjectType.GetProperty(BooleanSwitch);if(property==null||property.PropertyType!=typeof(bool)){thrownewArgumentException(BooleanSwitch+"不是"+validationContext.ObjectType.Name,BooleanSwitch)的有效布尔属性);}if((bool)property.GetValue(validationContext.ObjectInstance,null)&&(value==null||(!AllowEmptyStrings&&valueisstring&&String.IsNullOrWhiteSpace(valueasstring)))){returnnewValidationResult(FormatErrorMessage(validationContext.DisplayName));}返回ValidationResult.Success;}publicIEnumerableGetClientValidationRules(ModelMetadatametadata,ControllerContextcontext){objectmodel=context.Controller.ViewData.Model;boolrequired=(bool)model.GetType().GetProperty(BooleanSwitch).GetValue(model,null);如果(必需){yieldreturnnewModelClientValidationRequiredRule(FormatErrorMessage(metadata.DisplayName??metadata.PropertyName));}else//我们必须返回一个ModelCLientValidationRule,其中//ValidationType不为空,否则我们会得到一个异常//因为我们没有在客户端为'no添加验证规则trequired'//没有验证发生并且这有效,虽然它有点hack{yieldreturnnewModelClientValidationRule{ValidationType="notrequired",ErrorMessage=""};上面的代码将查找模型作为验证开关的属性(IsRequired是默认值)如果用作开关的布尔属性设置为true,则执行客户端和服务器端验证在用RuntimeRequiredValdiationAttribute修饰的属性上。重要的是要注意,此类假定用于验证开关的模型的任何属性都不会显示给最终用户以供编辑,即这不是RequiredIf验证器。实际上,还有另一种方法可以实现ValidationAttribute以及客户端验证,如此处所述。为了进行比较,我在上面所做的IClientValidatable路由是由同一作者概述的。请注意,这目前不适用于嵌套对象,例如如果一个属性修改了另一个对象包含的对象的属性,它将不起作用。有很多方法可以解决这个缺点,但到目前为止我还没有这样做。您可以使用RemoteAttribute。这应该对服务器执行一个不显眼的ajax调用以验证您的数据。正如我在上面的评论中所说,我使用反射做了类似的事情。您可以忽略其中的一些,例如您可能不需要字典,因为它只是为其提供自定义可翻译消息的一种方式。服务端代码:privatestaticDictionary_requiredValidationDictionary;privatestaticDictionaryRequiredValidationDictionary(UserBasemodel){if(_requiredValidationDictionary!=null)return_requiredValidationDictionary;_requiredValidationDictionary=newDictionary{{model.GetPropertyName(m=>m.Publication),ErrorMessageToken.PublicationRequired},{model.GetPropertyName(m=>m.Company),ErrorMessageToken.CompanyRequired},{model.GetPropertyName(m=>m.JobTitle),ErrorMessageToken.JobTitleRequired},{model.GetPropertyName(m=>m.KnownAs),ErrorMessageToken.KnownAsRequired},{model.GetPropertyName(m=>m.TelephoneNumber),ErrorMessageToken.TelephoneNoRequired},{model.GetPropertyName(m=>m.Address),ErrorMessageToken.AddressRequired},{model.GetPropertyName(m=>m.PostCode),ErrorMessageToken.PostCodeRequired},{model.GetPropertyName(m=>m.Country),ErrorMessageToken.CountryRequired}};返回_requiredValidationDictionary;}整数rnalstaticvoidSetCustomRequiredFields(ListrequiredFields,UserBasemodel,ITranslationEnginetranslationEngine){if(requiredFields==null||requiredFields.Countx.Trim())){ILocalisationToken令牌;if(!tokenDictionary.TryGetValue(requiredField,outtoken))token=LocalisationToken.GetFromString(string.Format("{0}required",requiredField));//添加到模型中。model.RequiredFields.Add(newRequiredField{FieldName=requiredField,ValidationMessage=translationEngine.ByToken(token)});}}internalstaticvoidCheckForRequiredField(ModelStateDictionarymodelState,TfieldValue,stringfieldName,IListrequiredFields,DictionarytokenDictionary){ILocalisationToken令牌;if(!tokenDictionary.TryGetValue(fieldName,outtoken))token=LocalisationToken.GetFromString(string.Format("{0}required",fieldName));if(requiredFields.Contains(fieldName)&&(Equals(fieldValue,default(T))||string.IsNullOrEmpty(fieldValue.ToString())))modelState.AddModelError(fieldName,token.Translate());}internalstaticvoidCheckForModelErrorForCustomRequiredFields(UserBasemodel,Paladin3DataAccessLayerclient,ICachecache,ModelStateDictionarymodelState){varrequiredFields=Common.CommaSeparatedFields.RegistSetting(SettingsRegistSettingscache:cache,defaultValue:String.Empty,region:null).选择(x=>x.Trim()).ToList();vartokenDictionary=RequiredValidationDictionary(模型);foreach(varpropertyintypeof(UserBase).GetProperties(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public)){CheckForRequiredField(modelState,property.GetValue(model,null),property.Name,requiredFields,tokenDictionary);在模型上我们有一个列表,上面基本上是一个有两个字符串的类,一个用于字段名称,一个用于错误消息一旦模型被传递到视图中,如果你想执行检查服务器端,你'您将需要一些jQuery来将验证内容添加到页面。客户端代码:$("#YOURFORM").validate();for(varx=0;x0){$field.rules("add",{required:true,messages:{required:""+requiredFields[x].ValidationMessage//required:"RequiredInput"}});$field.parent().addClass("formRequired");//添加一个类,以便用户在提交之前知道它是必填字段}}如果其中任何一个不是很清楚,我们深表歉意。请随时提出任何问题,我会尽力解释。我很长时间没有使用MVC4,所以如果我错了请原谅我,您可以使用jquery-val进行服务器端和客户端验证(如果您在创建您的应用程序时使用“Internet应用程序”模板,则已经有效project))和属性:以上就是C#学习教程:使用ASP.NETMVC4在运行时动态应用验证规则分享的全部内容。如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——publicclassDevice{publicintId{get;设置;}公共ICollection设置{get;set;}}publicclassSetting{[必需]publicintId{get;设置;}[Range(1,10)]publicstringValue{get;设置;}[必需]publicboolIsRequired{get;设置;}公共intMinLength{得到;设置;}公共intMaxLength{得到;联系右侧管理员删除。如需转载请注明出处: