我为我的MVC项目设置了一个自定义验证属性,我想使用该属性来验证用户选择上传的文件类型。该属性如下所示:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class AcceptedExtensionsAttribute : ValidationAttribute, IClientModelValidator
{
private List<string> AllowedExtensions { get; set; }
public AcceptedExtensionsAttribute(string fileExtensions)
{
AllowedExtensions = fileExtensions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var file = value as IFormFile;
if (file != null)
{
if (!AllowedExtensions.Any(y => file.FileName.EndsWith(y)))
{
return new ValidationResult(getErrorMessage());
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-acceptedextensions", getErrorMessage());
MergeAttribute(context.Attributes, "data-val-acceptedextensions-extensions", string.Join(',', AllowedExtensions));
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
private string getErrorMessage()
=> ErrorMessage ?? "Incorrect file format provided.";
}
以下是在属性上使用的属性:
[Required]
[AcceptedExtensions("jpg")]
public IFormFile Image { get; set; }
我还尝试使用以下jQuery添加客户端验证:
<script type="text/javascript">
$.validator.addMethod('acceptedextensions', function (value, element, params) {
var extensions = params[1].split(',');
var fileName = value;
for (var i = 0; i < extensions.length; i++) {
if (fileName.endsWith(extensions[i])) {
return true;
}
}
return false;
});
$.validator.unobtrusive.adapters.add('acceptedextensions', ['extensions'], function (options) {
options.rules['acceptedextensions'] = [options.element, options.params['extensions']];
options.messages['acceptedextensions'] = options.message;
});
</script>
问题在于未调用客户端验证方法。如果在对adapaters.add
的调用中添加了一个断点,则似乎可以添加该规则,但是之后再调用$('#Image').rules()
时,我可以看到该规则不再位于规则数组中。我很确定这是问题所在,因为我可以在jquery.validate.js的check
方法中看到使用此函数的规则。
我不太确定为什么未正确添加规则。奇怪的是,如果我添加如下规则:
$(options.element).rules("add", { acceptedextensions: options.params['extensions'] });
而不是这样:
options.rules['acceptedextensions'] = [options.element, options.params['extensions']];
然后添加了规则,但是我不确定该错误消息的处理方法,因为它似乎也没有正确添加。