DataAnnotations的FileExtensions属性在MVC中不起作用

Dfr*_*Dkn 8 .net c# asp.net-mvc file-upload data-annotations

我试图在MVC中使用HTML FileUpload控件上传文件.我想验证该文件只接受特定的扩展名.我已经尝试使用DataAnnotations命名空间的FileExtensions属性,但它不起作用.见下面的代码 -

public class FileUploadModel
    {
        [Required, FileExtensions(Extensions = (".xlsx,.xls"), ErrorMessage = "Please select an Excel file.")]
        public HttpPostedFileBase File { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

在控制器中,我正在编写如下代码 -

[HttpPost]
        public ActionResult Index(FileUploadModel fileUploadModel)
        {
            if (ModelState.IsValid)
                fileUploadModel.File.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), Path.GetFileName(fileUploadModel.File.FileName)));

            return View();
        }
Run Code Online (Sandbox Code Playgroud)

在View中,我写了下面的代码 -

@using (Html.BeginForm("Index", "FileParse", FormMethod.Post, new { enctype = "multipart/form-data"} ))
{
    @Html.Label("Upload Student Excel:")
    <input type="file" name="file" id="file"/>
    <input type="submit" value="Import"/>
    @Html.ValidationMessageFor(m => m.File)
}
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序并提供无效的文件扩展名时,它没有显示错误消息.我知道编写自定义验证属性的解决方案,但我不想使用自定义属性.请指出我哪里出错了.

Raf*_*lho 6

我有同样的问题,我解决了创建一个新的ValidationAttribute.

像这样:

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

        public FileExtensionsAttribute(string fileExtensions)
        {
            AllowedExtensions = fileExtensions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
        }

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

            if (file != null)
            {
                var fileName = file.FileName;

                return AllowedExtensions.Any(y => fileName.EndsWith(y));
            }

            return true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,只需使用:

[FileExtensions("jpg,jpeg,png,gif", ErrorMessage = "Your error message.")]
public HttpPostedFileBase Imagem { get; set; }
Run Code Online (Sandbox Code Playgroud)

我帮了.拥抱!


小智 6

就像 marai 回答的那样,FileExtension 属性仅适用于字符串属性。

在我的代码中,我使用该属性如下:

public class MyViewModel
{
    [Required]
    public HttpPostedFileWrapper PostedFile { get; set; }

    [FileExtensions(Extensions = "zip,pdf")]
    public string FileName
    {
        get
        {
            if (PostedFile != null)
                return PostedFile.FileName;
            else
                return "";
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在服务器端,如果发布的文件没有您在属性中指定的扩展名(在我的示例中为 .zip 和 .pdf),则 ModelState.IsValid 将为 false。

注意:如果您在回发后使用HTML.ValidationMessageFor帮助程序呈现错误消息(文件扩展名属性不在客户端验证,仅在服务器端验证),则需要为该属性指定另一个帮助程序FileName才能显示扩展错误消息:

@Html.ValidationMessageFor(m => m.PostedFile)
@Html.ValidationMessageFor(m => m.FileName)
Run Code Online (Sandbox Code Playgroud)


mar*_*rai 3

FileExtensions 属性不知道如何验证 HttpPostedFileBase。请尝试下面

[FileExtensions(Extensions = "xlsx|xls", ErrorMessage = "Please select an Excel file.")]
public string Attachment{ get; set; }
Run Code Online (Sandbox Code Playgroud)

在你的控制器中:

[HttpPost]
    public ActionResult Index(HttpPostedFileBase Attachment)
    {
        if (ModelState.IsValid)
        {
            if (Attachment.ContentLength > 0)
            {
                string filePath = Path.Combine(HttpContext.Server.MapPath("/Content/Upload"), Path.GetFileName(Attachment.FileName));
                Attachment.SaveAs(filePath);
            }
        }
        return RedirectToAction("Index_Ack"});
    }
Run Code Online (Sandbox Code Playgroud)