ASP.NET MVC 3: DataAnnotations.FileExtensionsAttribute не работает - PullRequest
8 голосов
/ 16 декабря 2011

Согласно документации MSDN, по умолчанию атрибут FileExtensionsAttribute (.NET 4.5) должен позволять мне загружать только файлы jpg, jpeg, gif и png - это то, что мне нужно.

Я попытался загрузить jpg без атрибута, все работает. Отлично. затем Я добавил атрибут в мою модель вида ..

[FileExtensions(ErrorMessage = "Please specify a valid image file (.jpg, .jpeg, .gif or .png)")]
public HttpPostedFileBase ImageFile { get; set; }

Нет радости. Проверка не пройдена, и отображается сообщение ErrorMessage. Кроме того, кажется, нет способа указать любые разрешенные пользовательские расширения файлов. В итоге я расширил атрибут FileExtensionsAttribute и использовал собственную логику проверки, которая работает, как и ожидалось. Но почему этот способ не работает?

Будет публиковать весь контроллер и просматривать при необходимости. Я использовал этот пример в качестве основы для логики загрузки, но с использованием DataAnnotations.FileExtensionsAttribute вместо Microsoft.Web.Mvc.FileExtensions .. Как загрузить изображения в ASP.NET MVC?

Ответы [ 4 ]

25 голосов
/ 30 ноября 2012

Поскольку System.ComponentModel.DataAnnotations.FileExtensionsAttribute запечатан.Я использую обертку для MVC 4.

public class HttpPostedFileExtensionsAttribute : DataTypeAttribute, IClientValidatable
{
    private readonly FileExtensionsAttribute _innerAttribute =
        new FileExtensionsAttribute();

    /// <summary>
    ///     Initializes a new instance of the <see cref="HttpPostedFileExtensionsAttribute" /> class.
    /// </summary>
    public HttpPostedFileExtensionsAttribute()
        : base(DataType.Upload)
    {
        ErrorMessage = _innerAttribute.ErrorMessage;
    }

    /// <summary>
    ///     Gets or sets the file name extensions.
    /// </summary>
    /// <returns>
    ///     The file name extensions, or the default file extensions (".png", ".jpg", ".jpeg", and ".gif") if the property is not set.
    /// </returns>
    public string Extensions
    {
        get { return _innerAttribute.Extensions; }
        set { _innerAttribute.Extensions = value; }
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
        ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "extension",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
        };
        rule.ValidationParameters["extension"] = _innerAttribute.Extensions;
        yield return rule;
    }

    /// <summary>
    ///     Applies formatting to an error message, based on the data field where the error occurred.
    /// </summary>
    /// <returns>
    ///     The formatted error message.
    /// </returns>
    /// <param name="name">The name of the field that caused the validation failure.</param>
    public override string FormatErrorMessage(string name)
    {
        return _innerAttribute.FormatErrorMessage(name);
    }

    /// <summary>
    ///     Checks that the specified file name extension or extensions is valid.
    /// </summary>
    /// <returns>
    ///     true if the file name extension is valid; otherwise, false.
    /// </returns>
    /// <param name="value">A comma delimited list of valid file extensions.</param>
    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file != null)
        {
            return _innerAttribute.IsValid(file.FileName);
        }

        return _innerAttribute.IsValid(value);
    }
}
5 голосов
/ 16 декабря 2011

Используйте свойство Extensions , чтобы установить их.Хотя согласно документации

Расширения имени файла или расширения по умолчанию (".png", ".jpg", ".jpeg" и ".gif"), если свойство имеетне установлено.

Вы можете установить его так же, как ErrorMessage.Более вероятная проблема заключается в том, что он не знает, как оценить, имеет ли HttpPostedFileBase правильное расширение.Вам нужно будет использовать один из фреймворка MVC или создать свой собственный.

1 голос
/ 04 сентября 2014

Я знаю, что это слишком поздно, но, возможно, это может кому-то помочь. Это модифицированная версия @jfeinour, которая также будет работать на клиентской стороне :

public class HttpPostedFileExtensionAttribute : ValidationAttribute, IClientValidatable {
    private readonly FileExtensionsAttribute _fileExtensionsAttribute = new FileExtensionsAttribute();

    public HttpPostedFileExtensionAttribute() {
        ErrorMessage = _fileExtensionsAttribute.ErrorMessage;
    }

    public string Extensions {
        get { return _fileExtensionsAttribute.Extensions; }
        set { _fileExtensionsAttribute.Extensions = value; }
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
        var rule = new ModelClientValidationRule {
            ValidationType = "extension",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
        };

        rule.ValidationParameters["extension"] =
            _fileExtensionsAttribute.Extensions
                .Replace(" ", string.Empty).Replace(".", string.Empty)
                .ToLowerInvariant();

        yield return rule;
    }

    public override string FormatErrorMessage(string name) {
        return _fileExtensionsAttribute.FormatErrorMessage(name);
    }

    public override bool IsValid(object value) {
        var file = value as HttpPostedFileBase;
        return _fileExtensionsAttribute.IsValid(file != null ? file.FileName : value);
    }
}
0 голосов
/ 19 декабря 2011

Атрибут FileExtensionsAttribute не знает, как проверить HttpPostedFileBase, поэтому я расширил его ..

/// <summary>
/// A File extensions attribute for verifying the file extensions of posted files from MVC forms.
/// </summary>
public class PostedFileBaseFileExtensionsAttribute : FileExtensionsAttribute
{

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var file = value as HttpPostedFileBase; 
        if (file == null)
        {
            return new ValidationResult("No File Specified");
        }

        return base.IsValid(file.FileName, validationContext);
    }
}

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

        var file = value as HttpPostedFileBase;
        return file == null ? ValidationResult.Success : base.IsValid(file.FileName, validationContext);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...