MVC3 How to check if HttpPostedFileBase is an image
Asked Answered
C

3

25

I have a controller like this:

public ActionResult Upload (int id, HttpPostedFileBase uploadFile)
{
....
}

How can I make sure that uploadFile is an image (jpg, png etc.)

I have tried with

using (var bitmapImage = new Bitmap (uploadFile.InputStream)) {..}

which throws an ArgumentException if bitmapImage can not be created.

Is there a better way for example by looking at uploadFile.FileName?

Confectionery answered 25/8, 2012 at 7:37 Comment(0)
C
65

You can check the HttpPostedFileBase object's properties for this

  • ContentType
  • FileName (check the file extensions, which you already know about :) )

enter image description here

Also here is a small method, I have prepared which you can use/extend...

private bool IsImage(HttpPostedFileBase file)
{
    if (file.ContentType.Contains("image"))
    {
        return true; 
    }

    string[] formats = new string[] { ".jpg", ".png", ".gif", ".jpeg" }; // add more if u like...

    // linq from Henrik Stenbæk
    return formats.Any(item => file.FileName.EndsWith(item, StringComparison.OrdinalIgnoreCase));
}

I have also written an article on this here

Ching answered 25/8, 2012 at 8:0 Comment(1)
Thaks - I have changed the foreach to: return formats.Any(item => file.FileName.EndsWith(item, StringComparison.OrdinalIgnoreCase));Calamite
W
20

You could check the file name and extension and MIME type but that might not be reliable because the user could simply rename the file before uploading. Here's a reliable way to achieve that by looking at the contents of the file: https://mcmap.net/q/112384/-how-to-validate-uploaded-file-in-asp-net-mvc

You could of course extend this to other known image type formats than PNG, like this:

public class ValidateFileAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file == null)
        {
            return false;
        }

        if (file.ContentLength > 1 * 1024 * 1024)
        {
            return false;
        }

        try
        {
            var allowedFormats = new[] 
            { 
                ImageFormat.Jpeg, 
                ImageFormat.Png, 
                ImageFormat.Gif, 
                ImageFormat.Bmp 
            };

            using (var img = Image.FromStream(file.InputStream))
            {
                return allowedFormats.Contains(img.RawFormat);
            }
        }
        catch { }
        return false;
    }
}
Whittington answered 25/8, 2012 at 8:32 Comment(1)
I think bringing across the example code, you should probably have removed the limitation wanted on the other post of 'not exceeding 1MB' by removing the 2nd if statement - doesn't help in answering this question.Leonardoleoncavallo
B
4

Or you can check it on client side thru html attribute 'accept' to filter the file asap:

@Html.TextBoxFor(x => x.HomeDeviceImage, new { @type = "file", @accept = "image/x-png, image/gif, image/jpeg" })

this will only show filetypes defined in your accept attribute as default. Beware, user can still change filetye to "All files", with this in mind, better check this:

Solved concern , a javascript snippet to check extension, and then do some editing to disable button like:

            $('input:submit').attr('disabled', true);

until file extension is correct. nevertheless have it checked on server side. :)

Bowers answered 3/1, 2014 at 3:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.