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?
You can check the HttpPostedFileBase
object's properties for this
- ContentType
- FileName (check the file extensions, which you already know about :) )
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
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://stackoverflow.com/a/6388927/29407
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;
}
}
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. :)