Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if uploaded file is an image in C# ASP.NET MVC

I have my controller

[HttpPost]
public ActionResult ChangeAvatar(HttpPostedFileBase file)
{
    AvatarHelper.AvatarUpdate(file, User.Identity.Name);
    return RedirectToAction("Index", "Profile");
}

And I already check if file is in jpeg/png format:

private static bool IsImage(string contentType)
{   
  return AllowedFormats.Any(format => contentType.EndsWith(format,   
             StringComparison.OrdinalIgnoreCase));
}

public static List<string> AllowedFormats
{
    get { return new List<string>() {".jpg", ".png", ".jpeg"}; }
}

What I need - it ensure that uploaded file is real image file and not txt file with image extension.

I convert my uploaded file like this:

using (var image = System.Drawing.Image.FromStream(postedFile.InputStream))
{
          ///image stuff
}

I am thinking about try/catch block on creating image from input stream but I wonder if there is good way to do it? Thanks)

P.S.

I wonder if there is another (more efficient way that try/catch block) way to check whether file is real image?

like image 756
makambi Avatar asked Mar 11 '13 11:03

makambi


2 Answers

You could use the RawFormat property:

private static ImageFormat[] ValidFormats = new[] { ImageFormat.Jpeg, ImageFormat.Png };
public bool IsValid(Stream image)
{
    try
    {
        using (var img = Image.FromStream(file.InputStream))
        {
            return ValidFormats.Contains(img.RawFormat);
        }
    }
    catch
    {
        return false;
    }
}

Also you could put this validation logic into a reusable validation attribute as I have shown in this post.

like image 103
Darin Dimitrov Avatar answered Oct 14 '22 10:10

Darin Dimitrov


My solution as an extension, actually checking if a base64 string is an image or not:

public static bool IsImage(this string base64String)
    {
        byte[] imageBytes = Convert.FromBase64String(base64String);

        var stream = new MemoryStream(imageBytes, 0, imageBytes.Length);
        try
        {
            stream.Write(imageBytes, 0, imageBytes.Length);
            System.Drawing.Image image = System.Drawing.Image.FromStream(stream, true);
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

Usage:

if(!"base64string".IsImage())
     throw new Exception("Not an image");
like image 36
Sam Jones Avatar answered Oct 14 '22 10:10

Sam Jones