使用自定义验证的FileExtension验证会创建重复和无效的data- *属性

古鲁帕萨德·J·饶(Guruprasad J Rao)

在我根据中提到的答案尝试过之后,提出了这个问题my previous question我遵循this article完全相同的方法,但是进行了验证,image files而不是doc files本文提到的方法。

说明:我可以input控制type=file上传图片文件,并且该文件存在于其中之一partialviewpartialview被装上clickbutton并要应用中validations提到的model,显式添加unobtrusive到中form但是,在遵循了上述文章中提到的所有设置之后,我也无法验证文件submitdata-*创建者unobtrusive validation也相当可疑,或者最好说成是无效的。下面的代码显示了我的设置,下面是html使用无效data-*属性的非侵入式验证创建的代码,可能是验证失败的原因。

<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="">

加载局部视图Js

$('.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>
}

最后是我的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));
    }
}
用户名

您需要移动块代码

$(function () {
  ....
}(jQuery));

$('.getpartial').on(..)函数内部到函数之前

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

当前,您加载内容,重新解析验证器,然后将添加方法添加到jquery验证中,但添加到后期(验证器已被解析)

旁注:您无需将验证功能包装在中$(function () {可以将其删除,$.validator...而不必jQuery.validator....像在代码中的其他地方那样简单地使用它

至于“腥”data-val-*属性,这正是您的代码生成的。您先生成一个ClientValidationRule命名的fileextensionsValidationType = "fileextensions";代码),然后添加它的一个属性也命名为fileextensionsValidationParameters.Add("fileextensions", ..)生成代码data-val-fileextensions-fileextensions="png,jpg,jpeg"。至于),生成代码data-val-fileextensions=""是为了存储错误消息,但尚未生成一个,因此它是一个空字符串。

我建议对您的代码进行一些更改。

  1. 将其重命名为,FileTypeAttribute以便您可以灵活地添加其他文件验证属性,例如FileSizeAttribute,验证最大大小。
  2. 在构造函数中,生成默认错误消息,例如add,private const string _DefaultErrorMessage = "Only the following file types are allowed: {0}";并在构造函数的最后一行包括ErrorMessage = string.Format(_DefaultErrorMessage, string.Join(" or ", ValidExtensions));
  3. 更改ValidationParameters.Add("fileextensions", ...)为(例如),ValidationParameters.Add("validtypes", ...)以便生成data-val-fileextensions-validtypes="png,jpg,jpeg"更有意义的代码(请注意,您需要将脚本更改为...add('fileextensions', ['validtypes'], function() ....

编辑

您的代码将无法使用<input type="file" multiple="multiple" ... />。为此,您的媒体资源必须是IEnumerable(请注意您对代码的一些小改动)

[FileType("png, jpg, jpeg")]
public IEnumerable<HttpPostedFileBase> Files { get; set; }

然后,验证属性需要检查集合中的每个文件

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

最后,脚本需要检查每个文件

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

创建自定义模型验证属性

空属性的自定义验证服务

自定义验证属性的依赖注入

如何验证JwtSecurityToken自定义属性

使用表单请求特定的自定义验证属性

在ASP.NET Core中使用Authorize属性和自定义Cookie身份验证

如何在使用自定义验证器解析器时使用验证名称和属性 [laravel 6]

如何在Angular 2.0中创建自定义验证指令(即验证属性)?

自定义StringLength验证属性的客户端验证

向JSON添加自定义属性会创建重复项

创建自定义验证属性C#服务器端

使用 http 服务的角度自定义验证 - 无法读取未定义的属性

jQuery验证数据属性中的自定义规则

如何验证属性/自定义配置文件?

HTML Razor中Step属性的自定义错误验证

Rails 中几个属性的自定义验证器

JQuery 自定义验证属性 MVC 核心

Laravel Backpack 自定义验证多个属性

集合内的自定义属性客户端验证

创建自定义属性

如何创建自定义 api 参数验证属性,该属性在 aspnet core 3 上返回错误请求?

在.NET Core Web API中使用自定义属性进行JWT身份验证

Yii2 自定义验证规则,使用三个属性比较函数

在Laravel验证程序中为嵌套属性使用自定义错误消息

如何在数据库实体的子模型上使用自定义验证属性?

尝试使用自定义验证属性时发生System.InvalidOperationException

如何使用ASP.NET Core中的自定义验证在索引处获取属性?

如何使用javascript或jquery验证自定义属性中是否存在某个值?

将自定义 JsonConverter 添加到 Web API 会影响传递给自定义验证属性的字符串值