如何在Asp.Net MVC 4中验证HttpPostedFileBase属性的文件类型?

费尔南多·派瓦(Fernando Paiva)

我正在尝试验证HttpPostedFileBase属性的文件类型以检查文件的类型,但是由于验证通过,因此我无法执行此操作。我该怎么办?

模型

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


}
用户名

由于您的属性继承自现有属性,因此需要在其中注册global.asax例如,请参考此答案),但是在这种情况下要这样做。您的验证代码无效,并且文件类型属性不应继承自RequiredAttribute-它需要继承自ValidationAttribute,如果要进行客户端验证,则还需要实现IClientValidatable用于验证文件类型的属性为(如果该属性用于IEnumerable<HttpPostedFileBase>并验证集合中的每个文件,则请注意此代码

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

它将应用于属性为

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

并认为

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

然后,需要以下脚本进行客户端验证(与jquery.validate.jsjquery.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;
}

请注意,您的代码正在尝试也验证文件的最大大小,该文件需要为单独的验证属性。有关验证最大允许大小的验证属性的示例,请参阅本文

此外,我建议将《 ASP.NET MVC 3验证的完整指南-第2部分》作为创建自定义验证属性的良好指南。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章