【问题标题】:Does the IClientValidator support input file?IClientValidator 是否支持输入文件?
【发布时间】:2018-09-17 18:05:31
【问题描述】:

编辑

我发现问题在于视图组件无法拥有@section (see ViewComponent and @Section #2910 ),因此使用不显眼的库添加自定义客户端验证似乎是不可能的(或者非常复杂)。此外,无法将所需的 javascript 包含到视图组件中,这让我很遗憾最初采用这种方法来模块化我的应用程序...


我正在学习使用客户端支持制作自定义验证属性。我能够为字符串属性实现一个自定义验证器,它工作得很好,但是当我尝试为输入文件创建一个验证器时它不起作用(即当我在我的计算机中选择一个文件时,应用程序不显示验证消息。服务器端验证有效。这是一些显示我的实现的代码。

模型的类

public class UploadPanelModel
{
    public int? ID { get; set; }
    public string Title { get; set; }
    public string Description { get; set; } //Raw HTML with the panel description
    [FileType(type:  "application/pdf")]
    [FileSize(maxSize: 5000000)]
    public IFormFile File { get; set; }
    public byte[] FileBytes { get; set; }
    public ModalModel Modal { get; set; } //Only used if the Upload panel uses a modal.

验证器

public class FileSizeAttribute : ValidationAttribute, IClientModelValidator
{
    private long _MaxSize { get; set; }
    public FileSizeAttribute (long maxSize)
    {
        _MaxSize = maxSize;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        UploadPanelModel panel = (UploadPanelModel)validationContext.ObjectInstance;
        return (panel.File==null || panel.File.Length <= _MaxSize) ?  ValidationResult.Success : new ValidationResult(GetFileSizeErrorMessage(_MaxSize));
    }
    private string GetFileSizeErrorMessage(long maxSize)
    {
        double megabytes = maxSize / 1000000.0;
        return $"El archivo debe pesar menos de {megabytes}MB";
    }
    public void AddValidation(ClientModelValidationContext context)
    {
        if(context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }
        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(context.Attributes, "data-val-filesize", GetFileSizeErrorMessage(_MaxSize));
        var maxSize = _MaxSize.ToString();
        MergeAttribute(context.Attributes, "data-val-filesize-maxsize", maxSize);         
    }
    private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
    {
        if (attributes.ContainsKey(key))
        {
            return false;
        }
        attributes.Add(key, value);
        return true;
    }
}

Razor 视图中的 javascript

@section Scripts{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}


<script type="text/javascript">
    $.validator.addMethod('filesize',
        function (value, element, params) {
            var size = $((params[0]).val()).size(),
                maxSize = params[1];
            if (size < maxSize) {
                return false;
            }
            else {
                return false;
            }
        }
    );
    $.validator.unobtrusive.adapters.add('filesize',
        ['maxSize'],
        function (options) {
            var element = $(options.form).find('input#File')[0];
            options.rules['filesize'] = [element, options.params['maxSize']];
            options.messages['filesize'] = options.message;
        }
    );
</script>

我总是在 javascript 方法中返回 false 以强制应用程序显示验证错误,而不管选择的文件,但它仍然不起作用。

【问题讨论】:

    标签: asp.net-core-mvc internet-explorer-11 asp.net-core-2.1


    【解决方案1】:

    你的addMethod() 函数会抛出一个错误,因为params[0] 不是一个jQuery 对象并且没有.val()(你也有$ 在错误的地方)。你需要使用

    var size = params[0].files[0].size;
    

    不过我建议你把脚本写成

    $.validator.unobtrusive.adapters.add('filesize', ['maxsize'], function (options) {
        options.rules['filesize'] = { maxsize: options.params.maxsize };
        if (options.message) {
            options.messages['filesize'] = options.message;
        }
    });
    
    $.validator.addMethod("filesize", function (value, element, param) {
        if (value === "") {
            return true;
        }
        var maxsize = parseInt(param.maxsize);
        if (element.files != undefined && element.files[0] != undefined && element.files[0].size != undefined) {
            var filesize = parseInt(element.files[0].size);
            return filesize <= maxsize ;
        }
        return true; // in case browser does not support HTML5 file API
    });
    

    【讨论】:

    • 您好。我尝试使用您的脚本,但没有成功。客户端验证似乎不适用于输入文件...
    • 当然可以——我的[FileType][FileSize] 属性都可以正常工作。使用浏览器逐步抛出代码并进行调试。
    • o.o 好的。我会再试一次,明天报告结果。
    • 我怀疑您将服务器端验证(完美运行)与客户端验证混淆了。应用程序将文件发送到服务器,但它应该在发送之前对其进行验证。
    • 我没有混淆任何东西。我有一个包含 50 多个验证属性的库,用于验证服务器 和客户端
    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 2011-02-28
    • 2020-06-18
    相关资源
    最近更新 更多