Jquery 使用自定义验证的FileExtension验证会创建重复且无效的数据-*属性

Jquery 使用自定义验证的FileExtension验证会创建重复且无效的数据-*属性,jquery,asp.net-mvc,validation,asp.net-mvc-3,jquery-validate,Jquery,Asp.net Mvc,Validation,Asp.net Mvc 3,Jquery Validate,这个问题是在我尝试了中提到的答案之后提出的。我采用了与完全相同的方法,但验证了图像文件,而不是本文中提到的文档文件 说明:我有一个输入控件type=file,用于上载图像文件,该控件存在于其中一个部分视图中。partialview在按钮的点击时加载。要应用模型中提到的验证,请在表单中明确添加不引人注目的。但是,在完成了上述文章中提到的所有设置之后,我无法验证提交上的文件,而且不引人注目的验证创建的数据-*非常可疑,或者说无效。下面是显示我的设置的代码,下面是通过使用无效的data-*属性进行不引

这个问题是在我尝试了中提到的答案之后提出的。我采用了与完全相同的方法,但验证了
图像文件
,而不是本文中提到的
文档文件

说明:我有一个
输入
控件
type=file
,用于上载图像文件,该控件存在于其中一个
部分视图
中。
partialview
按钮的
点击
时加载。要应用
模型
中提到的
验证
,请在
表单
中明确添加
不引人注目的
。但是,在完成了上述文章中提到的所有设置之后,我无法验证
提交
上的文件,而且
不引人注目的验证
创建的
数据-*
非常可疑,或者说无效。下面是显示我的设置的代码,下面是通过使用无效的
data-*
属性进行不引人注目的验证创建的
html
,这可能是验证失败的原因

<input data-charset="file" data-val="true" data-val-fileextensions="" data-val-fileextensions-fileextensions="png,jpg,jpeg" id="File" multiple="multiple" name="File" type="file" value="">
ModelClass

$('.getpartial').on('click', function () {
    $('.loadPartial').empty().load('/Home/GetView',function () {
        var form = $('form#frmUploadImages');
        form.data('validator', null);
        $.validator.unobtrusive.parse(form);
        $(function () {
            jQuery.validator.unobtrusive.adapters.add('fileextensions', ['fileextensions'], function (options) {
                var params = {
                    fileextensions: options.params.fileextensions.split(',')
                };
                options.rules['fileextensions'] = params;
                if (options.message) {
                    options.messages['fileextensions'] = options.message;
                }
            });

            jQuery.validator.addMethod("fileextensions", function (value, element, param) {
                var extension = getFileExtension(value);
                var validExtension = $.inArray(extension, param.fileextensions) !== -1;
                return validExtension;
            });

            function getFileExtension(fileName) {
                var extension = (/[.]/.exec(fileName)) ? /[^.]+$/.exec(fileName) : undefined;
                if (extension != undefined) {
                    return extension[0];
                }
                return extension;
            };
        }(jQuery));
    })
})
public class ImageUploadModel
{
    [FileValidation("png|jpg|jpeg")]
    public HttpPostedFileBase File { get; set; }
}
查看

@model ProjectName.Models.ImageUploadModel

@using (Html.BeginForm("UploadImages", "Admin", FormMethod.Post, htmlAttributes: new { id = "frmUploadImages", novalidate = "novalidate", autocomplete = "off", enctype = "multipart/form-data" }))
{
    <div class="form-group">
        <span class="btn btn-default btn-file">
            Browse @Html.TextBoxFor(m => m.File, new { type = "file", multiple = "multiple", data_charset = "file" })
        </span>&nbsp;
        <span class="text-muted" id="filePlaceHolder">No files selected</span>
        @Html.ValidationMessageFor(m => m.File, null, htmlAttributes: new { @class = "invalid" })
    </div>
    <div class="form-group">
        <button class="btn btn-primary addImage pull-right">
            <i class="fa fa-upload"></i> Upload
        </button>
    </div>
}
@model ProjectName.Models.ImageUploadModel
@使用(Html.BeginForm(“UploadImages”,“Admin”,FormMethod.Post,htmlAttributes:new{id=“frmUploadImages”,novalidate=“novalidate”,autocomplete=“off”,enctype=“multipart/form data”}))
{
浏览@Html.TextBoxFor(m=>m.File,新的{type=“File”,multiple=“multiple”,data_charset=“File”})
未选择任何文件
@ValidationMessageFor(m=>m.File,null,htmlAttributes:new{@class=“invalid”})
上传
}
最后是我的CustomFileValidation

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FileValidationAttribute : ValidationAttribute, IClientValidatable
{
    private List<string> ValidExtensions { get; set; }

    public FileValidationAttribute(string fileExtensions)
    {
        ValidExtensions = fileExtensions.Split('|').ToList();
    }

    public override bool IsValid(object value)
    {
        HttpPostedFileBase file = value as HttpPostedFileBase;
        if (file != null)
        {
            var fileName = file.FileName;
            var isValidExtension = ValidExtensions.Any(y => fileName.EndsWith(y));
            return isValidExtension;
        }
        return true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientFileExtensionValidationRule(ErrorMessage, ValidExtensions);
        yield return rule;
    }
}
public class ModelClientFileExtensionValidationRule : ModelClientValidationRule
{
    public ModelClientFileExtensionValidationRule(string errorMessage, List<string> fileExtensions)
    {
        ErrorMessage = errorMessage;
        ValidationType = "fileextensions";
        ValidationParameters.Add("fileextensions", string.Join(",", fileExtensions));
    }
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
公共类FileValidationAttribute:ValidationAttribute,IClientValidatable
{
私有列表{get;set;}
公共文件验证属性(字符串文件扩展名)
{
ValidExtensions=fileExtensions.Split(“|”).ToList();
}
公共覆盖布尔值有效(对象值)
{
HttpPostedFileBase file=值为HttpPostedFileBase;
如果(文件!=null)
{
var fileName=file.fileName;
var isValidExtension=ValidExtensions.Any(y=>fileName.EndsWith(y));
返回有效张力;
}
返回true;
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var规则=新的ModelClientFileExtensionValidationRule(ErrorMessage,ValidExtensions);
收益率-收益率规则;
}
}
公共类ModelClientFileExtensionValidationRule:ModelClientValidationRule
{
公共模型ClientFileExtensionValidationRule(字符串错误消息,列表文件扩展名)
{
ErrorMessage=ErrorMessage;
ValidationType=“fileextensions”;
Add(“fileextensions”,string.Join(“,”,fileextensions));
}
}

您需要移动块代码

$(function () {
  ....
}(jQuery));
从(..)上的
$('.getpartial')函数内部到其前面,以便

<script>
  $(function () {
    ....
  }(jQuery));

  $('.getpartial').on('click', function () { // or just $('.getpartial').click(function() {
    $('.loadPartial').empty().load('/Home/GetView',function () { // recommend .load('@Url.Action("GetView", "Home")', function() {
      var form = $('form#frmUploadImages');
      form.data('validator', null);
      $.validator.unobtrusive.parse(form);
    });
  });
</script>
然后验证属性需要检查集合中的每个文件

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FileTypeAttribute : ValidationAttribute, IClientValidatable
{
    private const string _DefaultErrorMessage = "Only the following file types are allowed: {0}";
    private IEnumerable<string> _ValidTypes { get; set; }

    public FileTypeAttribute(string validTypes)
    {
        _ValidTypes = validTypes.Split(',').Select(s => s.Trim().ToLower());
        ErrorMessage = string.Format(_DefaultErrorMessage, string.Join(" or ", _ValidTypes));
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        IEnumerable<HttpPostedFileBase> files = value as IEnumerable<HttpPostedFileBase>;
        if (files != null)
        {
            foreach(HttpPostedFileBase file in files)
            {
                if (file != null && !_ValidTypes.Any(e => file.FileName.EndsWith(e)))
                {
                    return new ValidationResult(ErrorMessageString);
                }
            }
        }
        return ValidationResult.Success;
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "filetype",
            ErrorMessage = ErrorMessageString
        };
        rule.ValidationParameters.Add("validtypes", string.Join(",", _ValidTypes));
        yield return rule;
    }
}
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
公共类FileTypeAttribute:ValidationAttribute,IClientValidable
{
private const string _DefaultErrorMessage=“仅允许以下文件类型:{0}”;
私有IEnumerable _有效类型{get;set;}
公共文件类型属性(字符串有效类型)
{
_ValidTypes=ValidTypes.Split(',')。选择(s=>s.Trim().ToLower());
ErrorMessage=string.Format(_DefaultErrorMessage,string.Join(“或“,_ValidTypes));
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
IEnumerable files=作为IEnumerable的值;
如果(文件!=null)
{
foreach(文件中的HttpPostedFileBase文件)
{
if(file!=null&&!_ValidTypes.Any(e=>file.FileName.EndsWith(e)))
{
返回新的ValidationResult(ErrorMessageString);
}
}
}
返回ValidationResult.Success;
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var规则=新ModelClientValidationRule
{
ValidationType=“filetype”,
ErrorMessage=ErrorMessageString
};
rule.ValidationParameters.Add(“validtypes”,string.Join(“,”,_validtypes));
收益率-收益率规则;
}
}
最后,脚本需要检查每个文件

$.validator.unobtrusive.adapters.add('filetype', ['validtypes'], function (options) {
    options.rules['filetype'] = { validtypes: options.params.validtypes.split(',') };
    options.messages['filetype'] = options.message;
});

$.validator.addMethod("filetype", function (value, element, param) {
    for (var i = 0; i < element.files.length; i++) {
        var extension = getFileExtension(element.files[0].name);
        if ($.inArray(extension, param.validtypes) === -1) {
            return false;
        }
    }
    return true;
});

function getFileExtension(fileName) {
    if (/[.]/.exec(fileName)) {
        return /[^.]+$/.exec(fileName)[0].toLowerCase();
    }
    return null;
}
$.validator.unobtrusive.adapters.add('filetype',['validtypes',]函数(选项){
options.rules['filetype']={validtypes:options.params.validtypes.split(',')};
options.messages['filetype']=options.message;
});
$.validator.addMethod(“文件类型”,函数(值、元素、参数){
对于(var i=0;i
2
jQuery.validator
getFileExtension()
函数不应该在
$('.getpartial')中。在('click',function(){
-将它们移动到方法之前(包括
$(function(){…}(jQuery))中的所有内容;
该代码也将打开
$.validator.unobtrusive.adapters.add('filetype', ['validtypes'], function (options) {
    options.rules['filetype'] = { validtypes: options.params.validtypes.split(',') };
    options.messages['filetype'] = options.message;
});

$.validator.addMethod("filetype", function (value, element, param) {
    for (var i = 0; i < element.files.length; i++) {
        var extension = getFileExtension(element.files[0].name);
        if ($.inArray(extension, param.validtypes) === -1) {
            return false;
        }
    }
    return true;
});

function getFileExtension(fileName) {
    if (/[.]/.exec(fileName)) {
        return /[^.]+$/.exec(fileName)[0].toLowerCase();
    }
    return null;
}