Поддерживает ли IClientValidator входной файл? - PullRequest
0 голосов
/ 17 сентября 2018

Редактировать

Я обнаружил, что проблема в том, что компоненты представления не могут иметь @section ( см. ViewComponent и @Section # 2910 ), поэтому добавление пользовательской проверки на стороне клиента с использованием ненавязчивой библиотеки кажется невозможным (или очень сложный). Более того, невозможность включения необходимого javascript в компонент View заставляет меня сожалеть о том, что я следую этому подходу для модульности моего приложения, в первую очередь ...


Я учусь создавать собственные атрибуты проверки с поддержкой на стороне клиента. Мне удалось реализовать пользовательский валидатор для свойства строки, и он работает довольно хорошо, но когда я попытался сделать таковой для входного файла, он не работает (т.е. когда я выбираю файл на моем компьютере, приложение не отображается сообщения проверки. Проверка на стороне сервера работает. Вот некоторый код, который показывает мою реализацию.

Класс модели

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

JavaScript в Razor View

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

Я всегда возвращаю false в методе javascript, чтобы приложение показывало ошибку проверки независимо от выбранного файла, но оно все равно не работает.

1 Ответ

0 голосов
/ 18 сентября 2018

Ваша функция 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
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...