gpt4 book ai didi

c# - 使用 AttributeTargets.Class 对自定义 ValidationAttribute 进行客户端验证

转载 作者:太空狗 更新时间:2023-10-30 00:57:13 25 4
gpt4 key购买 nike

是否可以为类范围内使用的自定义 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;
}
}

谢谢。

最佳答案

我在寻找同一问题的解决方案时找到了这个答案,并想出了一个解决方法。

用 2 个代替 1 个 ValidationAttribute:

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
}
}

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;
}
}

在客户端执行时,服务器属性被忽略,反之亦然。

如果您需要在类上有一个验证属性,验证可能会针对多个字段进行。我放入了一些用于将附加参数传递给客户端验证方法的样板代码,但它没有像我预期的那样工作。在我的实际代码中,我注释掉了 viewContext 和 dependentProperty1 变量,并且只是将“DependentProperty1”字符串传递给 rule.ValidationParameters.Add 方法的第二个参数。出于某种原因,我得到了一个不正确的 HtmlFieldPrefix。如果有人可以提供帮助,请发表评论...

无论如何,你最终会得到一个像这样的 View 模型:

[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; }
}

像这样的客户端脚本:

/// <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;
}
);

像这样的 View :

@Html.EditorFor(m => m.Value)
@Html.EditorFor(m => m.DependentProperty1)
@Html.ValidationMessageFor(m => m.Value)
@Html.ValidationMessageFor(m => m)

然后,如果您禁用了客户端验证,则会显示 @Html.ValidationMessageFor(m => m) 而不是属性的那个。

关于c# - 使用 AttributeTargets.Class 对自定义 ValidationAttribute 进行客户端验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5803314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com