Joz*_*avý 4 c# model-view-controller class client-side-validation attributeusage
是否可以对用于Class范围的自定义ValidationAttribute进行客户端验证?例如我的MaxLengthGlobal,它应确保所有输入字段的全局最大限制。
[AttributeUsage(AttributeTargets.Class)]
public class MaxLengthGlobalAttribute : ValidationAttribute, IClientValidatable
{
public int MaximumLength
{
get;
private set;
}
public MaxLengthGlobalAttribute(int maximumLength)
{
this.MaximumLength = maximumLength;
}
public override bool IsValid(object value)
{
var properties = TypeDescriptor.GetProperties(value);
foreach (PropertyDescriptor property in properties)
{
var stringValue = property.GetValue(value) as string;
if (stringValue != null && (stringValue.Length > this.MaximumLength))
{
return false;
}
}
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = this.FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "maxlengthglobal",
};
rule.ValidationParameters.Add("maxlength", this.MaximumLength);
yield return rule;
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢。
我在寻找相同问题的解决方案时找到了这个答案,并提出了解决方法。
代替1 ValidationAttribute,使用2:
1.)ServerValidationAttribute将位于该类上,并且不会实现IClientValidatable。
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MyCustomServerValidationAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
// remember to cast to the class type, not property type
// ... return true or false
}
}
Run Code Online (Sandbox Code Playgroud)
2.)ClientValidationAttribute将位于字段/属性上,并将实现IClientValidatable,但IsValid覆盖始终返回true。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,
AllowMultiple = false, Inherited = true)]
public class MyCustomClientValidationAttribute : ValidationAttribute,
IClientValidatable
{
public override bool IsValid(object value)
{
return true;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessage,
ValidationType = "mycustomvalidator",
};
var viewContext = (ViewContext)context;
var dependentProperty1 = viewContext.ViewData.TemplateInfo
.GetFullHtmlFieldId("DependentProperty1");
//var prefix = viewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
rule.ValidationParameters.Add("dependentproperty1", dependentProperty1);
yield return rule;
}
}
Run Code Online (Sandbox Code Playgroud)
在客户端上执行时,服务器属性将被忽略,反之亦然。
如果您需要在类上具有验证属性,则有可能针对多个字段进行验证。我添加了一些样板代码,用于将其他参数传递给客户端验证方法,但是它没有按预期工作。在我的实际代码中,我已注释掉viewContext和dependentProperty1变量,并仅将一个“ DependentProperty1”字符串传递给rule.ValidationParameters.Add方法的第二个参数。由于某种原因,我得到了不正确的HtmlFieldPrefix。如果有人可以提供帮助,请发表评论...
无论如何,您最终会得到如下所示的视图模型:
[MyCustomServerValidation(ErrorMessage = MyCustomValidationMessage)]
public class MyCustomViewModel
{
private const string MyCustomValidationMessage = "user error!";
[Display(Name = "Email Address")]
[MyCustomClientValidation(ErrorMessage = MyCustomValidationMessage)]
public string Value { get; set; }
[HiddenInput(DisplayValue = false)]
public string DependentProperty1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
客户端脚本如下:
/// <reference path="jquery-1.6.2.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
$.validator.addMethod('mycustomvalidator', function (value, element, parameters) {
var dependentProperty1 = $('#' + parameters['dependentproperty1']).val();
// return true or false
});
$.validator.unobtrusive.adapters.add('mycustomvalidator', ['dependentproperty1'],
function (options) {
options.rules['mycustomvalidator'] = {
dependentproperty1: options.params['dependentproperty1']
};
options.messages['mycustomvalidator'] = options.message;
}
);
Run Code Online (Sandbox Code Playgroud)
像这样的视图:
@Html.EditorFor(m => m.Value)
@Html.EditorFor(m => m.DependentProperty1)
@Html.ValidationMessageFor(m => m.Value)
@Html.ValidationMessageFor(m => m)
Run Code Online (Sandbox Code Playgroud)
然后,如果禁用了客户端验证,@Html.ValidationMessageFor(m => m)则会显示,而不显示该属性的。
| 归档时间: |
|
| 查看次数: |
2224 次 |
| 最近记录: |