简体   繁体   中英

FileExtensions attribute of DataAnnotations not working in MVC

I am trying to upload a file using HTML FileUpload control in MVC. I want to validate the file to accept only specific extensions. I have tried using FileExtensions attribute of DataAnnotations namespace, but its not working. See code below -

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

In the controller, I am writing the code as below -

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

            return View();
        }

In View, I have written below code -

@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)
}

When i run the application and give an invalid file extension, its not showing me the error message. I am aware of solution to write custom validation attribute, but I dont want to use custom attribute. Please point out where I am going wrong.

I had the same problem and I resolved creating a new ValidationAttribute.

Like this:

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

Now, just use this:

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

I have helped. Hugs!

The FileExtensions Attribute does not know how to verify a HttpPostedFileBase. Please try below

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

In your controller:

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

Like marai answered, the FileExtension Attribute only works on string properties.

In my code, i use the attribute as follows:

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

Then, in server side, ModelState.IsValid will be false if the postedfile doesn't have the entensions that you specify in the attribute (.zip and .pdf in my example).

Note: If you are using the HTML.ValidationMessageFor helper to render the error message after PostBack (The File Extension Attribute does not validate on client side, only server side), you need to specify another helper for the FileName property in order to display the extension error message:

@Html.ValidationMessageFor(m => m.PostedFile)
@Html.ValidationMessageFor(m => m.FileName)

I used the code above in FileExtensions attribute of DataAnnotations not working in MVC , I just did a couple of changes to: 1)avoid namespace collisions and 2) to use IFormFile instead of the original HttpPostedFileBase. Well, maybe is usefull to someone.

My code:

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

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

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

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

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

        return true;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM