Data annotation for IFormFile so it only allows files with .png, .jpg or .jpeg extension

Viewed 2934

I'm using ASP.NET Core MVC. I need a data annotation/custom data annotation for IFormFile, that check the file selected/uploaded is an Image, the extension of the image has to match *.png, *.jpg or *.jpeg . This is the view model

public class ProductViewModel 
{
    [Display(Name = "Image")]
    [Required(ErrorMessage = "Pick an Image")]
    //[CheckIfItsAnImage(ErrorMessage = "The file selected/uploaded is not an image")]
    public IFormFile File { get; set; }
}
3 Answers

Chameera is pretty close with his answer but unfortunately the built in FileExtensions DataAnnotation only works on strings and not on IFormFile. Here is the solution:

public class ProductViewModel 
{
    [Display(Name = "Image")]
    [Required(ErrorMessage = "Pick an Image")]
    public IFormFile File { get; set; }

    [FileExtensions(Extensions = "jpg,jpeg")]
    public string FileName => File?.FileName;
}

Use

public class AllowedExtensionsAttribute : ValidationAttribute
{
    private readonly string[] _extensions;

    public AllowedExtensionsAttribute(string[] extensions)
    {
        _extensions = extensions;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var file = value as IFormFile;
        var extension = Path.GetExtension(file.FileName);
        if (file != null)
        {
            if (!_extensions.Contains(extension.ToLower()))
            {
                return new ValidationResult(GetErrorMessage());
            }
        }
        return ValidationResult.Success;
    }

    public string GetErrorMessage()
    {
        return $"Your image's filetype is not valid.";
    }
}

put to your code

public class ProductViewModel 
{

    [Display(Name = "Image")]
    [Required(ErrorMessage = "Pick an Image")]
    [AllowedExtensions(new string[] { ".jpg", ".jpeg", ".png" })]
    public IFormFile File { get; set; }

}

Based on Do Nhu Vy answer. You can also implement the custom data validation in this way:

public class AllowedExtensionsAttribute : ValidationAttribute
{
    private readonly string[] _extensions;

    public AllowedExtensionsAttribute(string[] extensions)
    {
        _extensions = extensions;
    }


    public override bool IsValid(object value)
    {
        if (value is null)
            return true;

        var file = value as IFormFile;
        var extension = Path.GetExtension(file.FileName);

        if (!_extensions.Contains(extension.ToLower()))
            return false;

        return true;
    }
}

And then on your view model specify the Error Message:

public class ProductViewModel 
{
    [Display(Name = "Image")]
    [Required(ErrorMessage = "Pick an Image")]
    [FileExtensions("jpg,jpeg,png", ErrorMessage = "Your image's filetype is not valid.")]
    public IFormFile File { get; set; }
}
Related