Asp.net mvc 4 如何在Asp.NETMVC4中验证HttpPostedFileBase属性的文件类型?

Asp.net mvc 4 如何在Asp.NETMVC4中验证HttpPostedFileBase属性的文件类型?,asp.net-mvc-4,Asp.net Mvc 4,我正在尝试验证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 Htt

我正在尝试验证
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>

埃斯科尔哈图片
@TextBoxFor(model=>model.imagem,新的{Class=“formcontrol”,placeholder=“informeaimagem”,type=“file”})
@Html.ValidationMessageFor(model=>model.imagem)
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;
    }


}
使用系统;
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations;
使用系统图;
使用系统、绘图、成像;
使用System.Linq;
使用System.Web;
//验证文件是否为有效图像
公共类ValidateFileAttribute:RequiredAttribute{
公共覆盖布尔值有效(对象值)
{
bool isValid=false;
var file=作为HttpPostedFileBase的值;
如果(file==null | | file.ContentLength>1*1024*1024)
{
返回有效;
}
if(IsFileTypeValid(文件))
{
isValid=true;
}
返回有效;
}
私有bool IsFileTypeValid(HttpPostedFileBase文件)
{
bool isValid=false;
尝试
{
使用(var img=Image.FromStream(file.InputStream))
{
if(IsOneOfValidFormats(img.RawFormat))
{
isValid=true;
} 
}
}
抓住
{
//图像无效
}
返回有效;
}
私有bool IsOneOfValidFormats(ImageFormat-rawFormat)
{
列表格式=getValidFormats();
foreach(格式中的ImageFormat)
{
if(rawFormat.Equals(格式))
{
返回true;
}
}
返回false;
}
私有列表getValidFormats()
{
列表格式=新列表();
Add(ImageFormat.Png);
格式。添加(ImageFormat.Jpeg);
//在此处添加类型
返回格式;
}
}

由于您的属性继承自现有属性,因此需要在
全局.asax中注册它(请参阅示例),但是在您的情况下不要这样做。您的验证代码不起作用,并且文件类型属性不应从
RequiredAttribute
继承-它需要从
ValidationAttribute
继承,如果您想要客户端验证,那么它还需要实现
iclientvalidable
。验证文件类型的属性是(请注意,此代码用于
IEnumerable
属性,并验证集合中的每个文件)

[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
公共类FileTypeAttribute:ValidationAttribute,IClientValidable
{
private const string _DefaultErrorMessage=“仅允许以下文件类型:{0}”;
私有IEnumerable _有效类型{get;set;}
公共文件类型属性(字符串有效类型)
{
_ValidTypes=ValidTypes.Split(',')。选择(s=>s.Trim().ToLower());
ErrorMessage=string.Format(_DefaultErrorMessage,string.Join(“或“,_ValidTypes));
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
IEnumerable files=作为IEnumerable的值;
如果(文件!=null)
{
foreach(文件中的HttpPostedFileBase文件)
{
if(file!=null&&!_ValidTypes.Any(e=>file.FileName.EndsWith(e)))
{
返回新的ValidationResult(ErrorMessageString);
}
}
}
返回ValidationResult.Success;
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var规则=新ModelClientValidationRule
{
ValidationType=“filetype”,
ErrorMessage=ErrorMessageString
};
rule.ValidationParameters.Add(“validtypes”,string.Join(“,”,_validtypes));
收益率-收益率规则;
}
}
它将作为一个属性应用于一个属性

[文件类型(“JPG,JPEG,PNG”)]
公共IEnumerable附件{get;set;}
在我看来

@Html.TextBoxFor(m=>m.Attachments,新的{type=“file”,multiple=“multiple”})
@Html.ValidationMessageFor(m=>m.Attachments)
客户端验证需要以下脚本(与
jquery.validate.js
jquery.validate.unobtrusive.js结合使用

$.validator.unobtrusive.adapters.add('filetype',['validtypes',]函数(选项){
options.rules['filetype']={validtypes:options.params.validtypes.split(',')};
options.messages['filetype']=options.message;
});
$.validator.addMethod(“文件类型”,函数(值、元素、参数){
对于(var i=0;i
请注意,您的代码还试图验证文件的最大大小,该文件需要是一个单独的验证属性。有关验证允许的最大大小的验证属性的示例,请参阅


此外,我建议作为创建自定义验证属性的良好指南,请注意默认情况下EndsWith区分大小写。因此,我将更改此设置:

if (file != null && !_ValidTypes.Any(e => file.FileName.EndsWith(e)))
对此

if (file != null && !_ValidTypes.Any(e => file.FileName.EndsWith(e, StringComparison.OrdinalIgnoreCase)))

您的
ValidateFileAttribute
不应继承自
RequiredAttribute