MVC表单自定义客户端验证问题

时间:2018-08-07 14:33:25

标签: jquery asp.net-core unobtrusive-validation

我为我的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']];

然后添加了规则,但是我不确定该错误消息的处理方法,因为它似乎也没有正确添加。

0 个答案:

没有答案