Могу ли я получить доступ к свойствам HttpPostedFileBase в проверке jQuery? - PullRequest
1 голос
/ 04 марта 2012

В настоящее время я создаю несколько пользовательских атрибутов для проверки загруженного файла.

Одним из которых является FileSizeAttribute для обеспечения определенных ограничений (например, не может быть больше, чем x байтов или меньше, чем y байтов).

Есть ли способ получить доступ к свойству ContentLength HttpPostedFileBase? Я читал учебник по проверке расширений файлов , и автор показал пример кода для простой проверки расширений файлов.

Я хотел бы перейти к проверке размера файла на стороне клиента (в дополнение к стороне сервера), чтобы я мог сказать им, прежде чем они даже загрузятся, если он выходит за пределы размера.

Из доступного фрагмента кода кажется, что он имеет доступ только к имени файла:

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

Я здесь не прав или я что-то упускаю? Я никогда не использовал jQuery, и у меня есть беглое знание JavaScript, поэтому я не знаю, возможно ли это вообще.

1 Ответ

3 голосов
/ 04 марта 2012

Это может быть сделано, если браузер поддерживает File API . Это простой вопрос запроса свойства size.

Вот пример:

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

    public FileExtensionsAttribute(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));
            var isValidContentLength = file.ContentLength < MaxContentLength;
            return isValidExtension && isValidContentLength;
        }
        return true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ValidationType = "file";
        rule.ErrorMessage = this.FormatErrorMessage(ErrorMessage);
        rule.ValidationParameters["fileextensions"] = string.Join(",", ValidExtensions);
        rule.ValidationParameters["maxcontentlength"] = MaxContentLength.ToString();
        yield return rule;
    }
}

Модель:

public class MyViewModel
{
    [FileExtensions("txt|doc", MaxContentLength = 200000)]
    public HttpPostedFileBase File { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

Вид:

@model MyViewModel
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
    (function ($) {
        var getFileExtension = function (fileName) {
            var extension = (/[.]/.exec(fileName)) ? /[^.]+$/.exec(fileName) : undefined;
            if (extension != undefined) {
                return extension[0];
            }
            return extension;
        };

        var getFileSize = function (fileElement) {
            if (fileElement.files && fileElement.files.length > 0) {
                return fileElement.files[0].size;
            }
            return -1;
        };

        $.validator.unobtrusive.adapters.add(
            'file', ['fileextensions', 'maxcontentlength'], function (options) {
                var params = {
                    fileextensions: options.params.fileextensions.split(','),
                    maxcontentlength: options.params.maxcontentlength
                };
                options.rules['file'] = params;
                if (options.message) {
                    options.messages['file'] = options.message;
                }
            }
        );

        $.validator.addMethod('file', function (value, element, params) {
            var extension = getFileExtension(value);
            var validExtension = $.inArray(extension, params.fileextensions) !== -1;
            var fileSize = getFileSize(element);
            return validExtension && fileSize < parseInt(params.maxcontentlength);
        }, '');

    })(jQuery);
</script>

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.LabelFor(x => x.File)
    @Html.EditorFor(x => x.File)
    @Html.ValidationMessageFor(x => x.File)
    <button type="submit">OK</button>
}

Шаблон редактора (~/Views/Shared/EditorTemplates/HttpPostedFileBase):

@model HttpPostedFileBase
@Html.TextBoxFor(model => model, new { type = "file" })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...