FileExtensions attribute of DataAnnotations not working in MVC

16,381

Solution 1

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!

Solution 2

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)

Solution 3

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

Solution 4

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;
    }
}
Share:
16,381

Related videos on Youtube

DfrDkn
Author by

DfrDkn

A programmer by profession and an enthusiast on learning new things. :)

Updated on September 16, 2022

Comments

  • DfrDkn
    DfrDkn over 1 year

    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.

  • IEnjoyEatingVegetables
    IEnjoyEatingVegetables over 5 years
    Why did you not separate the extensions with commas?
  • Kash
    Kash about 3 years
    A nice solution @DanielSilva. Works perfectly fine. But the downside is that, it's working only in Server Side. Is there any workaround, so that it works in Client Side as well?
  • Patee Gutee
    Patee Gutee about 3 years
    Thanks this works great if there's file selected. But if there's no file selected, only the Required validation should fire. In this case, both validations does. Is there remedy for this issue?
  • Patee Gutee
    Patee Gutee about 3 years
    I got it working! When PostedFile is null, it should return null instead of returning "".