asp.net-mvc-4 - net - validationattribute



Comment valider le type de fichier de l'attribut HttpPostedFileBase dans Asp.Net MVC 4? (1)

Étant donné que votre attribut hérite des attributs existants et existants, il doit être enregistré dans global.asax (reportez - vous à cette réponse pour un exemple), mais ne le faites pas dans votre cas. Votre code de validation ne fonctionne pas et un attribut de type de fichier ne doit pas hériter de RequiredAttribute . Il doit hériter de ValidationAttribute . Si vous souhaitez une validation côté client, vous devez également implémenter IClientValidatable . Un attribut pour valider les types de fichier serait (notez ce code s'il s'agit d'une propriété qui est IEnumerable<HttpPostedFileBase> et valide chaque fichier de la collection).

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

Il serait appliqué à une propriété comme

[FileType("JPG,JPEG,PNG")]
public IEnumerable<HttpPostedFileBase> Attachments { get; set; }

et dans la vue

@Html.TextBoxFor(m => m.Attachments, new { type = "file", multiple = "multiple" })
@Html.ValidationMessageFor(m => m.Attachments)

Les scripts suivants sont ensuite requis pour la validation côté client (en conjonction avec jquery.validate.js et jquery.validate.unobtrusive.js

$.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[i].name);
        if ($.inArray(extension, param.validtypes) === -1) {
            return false;
        }
    }
    return true;
});

function getFileExtension(fileName) {
    if (/[.]/.exec(fileName)) {
        return /[^.]+$/.exec(fileName)[0].toLowerCase();
    }
    return null;
}

Notez que votre code tente également de valider la taille maximale du fichier, qui doit être un attribut de validation distinct. Pour obtenir un exemple d'attribut de validation qui valide la taille maximale autorisée, consultez cet article .

De plus, je recommande le Guide complet de validation dans ASP.NET MVC 3 - Partie 2, qui constitue un bon guide pour la création d'attributs de validation personnalisés.

J'essaie de valider un type de fichier d'attribut HttpPostedFileBase pour vérifier le type de fichier, mais je ne peux pas le faire car la validation est réussie. Comment pourrais-je faire ça?

en essayant

Modèle

public class EmpresaModel{

[Required(ErrorMessage="Choose a file .JPG, .JPEG or .PNG file")]
[ValidateFile(ErrorMessage = "Please select a .JPG, .JPEG or .PNG file")]
public HttpPostedFileBase imagem { get; set; }

}

HTML

<div class="form-group">
      <label for="@Html.IdFor(model => model.imagem)" class="cols-sm-2 control-label">Escolha a imagem <img src="~/Imagens/required.png" height="6" width="6"></label>
       @Html.TextBoxFor(model => Model.imagem, new { Class = "form-control", placeholder = "Informe a imagem", type = "file" })
       @Html.ValidationMessageFor(model => Model.imagem)
</div>

ValidateFileAttribute

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Web;

//validate file if a valid image
public class ValidateFileAttribute : RequiredAttribute{

    public override bool IsValid(object value)
    {
        bool isValid = false;
        var file = value as HttpPostedFileBase;

        if (file == null || file.ContentLength > 1 * 1024 * 1024)
        {
            return isValid;
        }

        if (IsFileTypeValid(file))
        {
            isValid = true;
        }

        return isValid;
    }

    private bool IsFileTypeValid(HttpPostedFileBase file)
    {
        bool isValid = false;

        try
        {
            using (var img = Image.FromStream(file.InputStream))
            {
                if (IsOneOfValidFormats(img.RawFormat))
                {
                    isValid = true;
                } 
            }
        }
        catch 
        {
            //Image is invalid
        }
        return isValid;
    }

    private bool IsOneOfValidFormats(ImageFormat rawFormat)
    {
        List<ImageFormat> formats = getValidFormats();

        foreach (ImageFormat format in formats)
        {
            if(rawFormat.Equals(format))
            {
                return true;
            }
        }
        return false;
    }

    private List<ImageFormat> getValidFormats()
    {
        List<ImageFormat> formats = new List<ImageFormat>();
        formats.Add(ImageFormat.Png);
        formats.Add(ImageFormat.Jpeg);        
        //add types here
        return formats;
    }


}




asp.net-mvc-4