c# - displayname - model annotation mvc
Determine si el archivo cargado es imagen(cualquier formato) en MVC (7)
Como primer paso, debe formar una lista blanca alrededor de los tipos MIME aceptables frente a la propiedad ContentType
.
Así que estoy usando este código para ver:
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" />
</form>
Esto para el modelo:
[HttpPost]
public ActionResult Index(HttpPostedFileBase file) {
if (file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
Funciona muy bien a menos que el usuario agregue un archivo que no sea una imagen. ¿Cómo puedo asegurar que el archivo cargado es una imagen? Gracias
En caso de que pueda ayudar a alguien, aquí hay un método estático para HttpPostedFileBase que verifica si un archivo cargado es una imagen:
public static class HttpPostedFileBaseExtensions
{
public const int ImageMinimumBytes = 512;
public static bool IsImage(this HttpPostedFileBase postedFile)
{
//-------------------------------------------
// Check the image mime types
//-------------------------------------------
if (postedFile.ContentType.ToLower() != "image/jpg" &&
postedFile.ContentType.ToLower() != "image/jpeg" &&
postedFile.ContentType.ToLower() != "image/pjpeg" &&
postedFile.ContentType.ToLower() != "image/gif" &&
postedFile.ContentType.ToLower() != "image/x-png" &&
postedFile.ContentType.ToLower() != "image/png")
{
return false;
}
//-------------------------------------------
// Check the image extension
//-------------------------------------------
if (Path.GetExtension(postedFile.FileName).ToLower() != ".jpg"
&& Path.GetExtension(postedFile.FileName).ToLower() != ".png"
&& Path.GetExtension(postedFile.FileName).ToLower() != ".gif"
&& Path.GetExtension(postedFile.FileName).ToLower() != ".jpeg")
{
return false;
}
//-------------------------------------------
// Attempt to read the file and check the first bytes
//-------------------------------------------
try
{
if (!postedFile.InputStream.CanRead)
{
return false;
}
//------------------------------------------
//check whether the image size exceeding the limit or not
//------------------------------------------
if (postedFile.ContentLength > ImageMinimumBytes)
{
return false;
}
byte[] buffer = new byte[ImageMinimumBytes];
postedFile.InputStream.Read(buffer, 0, ImageMinimumBytes);
string content = System.Text.Encoding.UTF8.GetString(buffer);
if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|<pre|<table|<a/s+href|<img|<plaintext|<cross/-domain/-policy",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
{
return false;
}
}
catch (Exception)
{
return false;
}
//-------------------------------------------
// Try to instantiate new Bitmap, if .NET will throw exception
// we can assume that it''s not a valid image
//-------------------------------------------
try
{
using (var bitmap = new System.Drawing.Bitmap(postedFile.InputStream))
{
}
}
catch (Exception)
{
return false;
}
finally
{
postedFile.InputStream.Position = 0;
}
return true;
}
}
Edit 10/02/2017: de acuerdo con una edición sugerida, se agregó una declaración final para restablecer la transmisión, para que podamos usarla más adelante.
Implementación de una manera mucho más limpia,
public static class FileExtensions
{
private static readonly IDictionary<string, string> ImageMimeDictionary = new Dictionary<string, string>
{
{ ".bmp", "image/bmp" },
{ ".dib", "image/bmp" },
{ ".gif", "image/gif" },
{ ".svg", "image/svg+xml" },
{ ".jpe", "image/jpeg" },
{ ".jpeg", "image/jpeg" },
{ ".jpg", "image/jpeg" },
{ ".png", "image/png" },
{ ".pnz", "image/png" }
};
public static bool IsImage(this string file)
{
if (string.IsNullOrEmpty(file))
{
throw new ArgumentNullException(nameof(file));
}
var extension = Path.GetExtension(file);
return ImageMimeDictionary.ContainsKey(extension.ToLower());
}
}
No tiene el compilador a la mano, pero algo como esto debería hacer:
try
{
var bitmap = Bitmap.FromStream( file.InputStream );
// valid image stream
}
catch
{
// not an image
}
Para cualquiera que se encuentre con esto.
También podría usar un file.ContentType.Contains("image")
para verificar si el tipo de contenido es de image / *.
if(file.ContentLength > 0 && file.ContentType.Contains("image"))
{
//valid image
}
else
{
//not a valid image
}
No estoy seguro de si esta es la mejor práctica, pero funciona para mí.
Usar en clase de ayudante estático:
public static bool IsImage(HttpPostedFileBase postedFile)
{
try {
using (var bitmap = new System.Drawing.Bitmap(postedFile.InputStream))
{
return !bitmap.Size.IsEmpty;
}
}
catch (Exception)
{
return false;
}
}
}
Usar en ASP.NET MVC viewmodel:
public class UploadFileViewModel
{
public HttpPostedFileBase postedFile { get; set; }
public bool IsImage()
{
try {
using (var bitmap = new System.Drawing.Bitmap(this.postedFile.InputStream))
{
return !bitmap.Size.IsEmpty;
}
}
catch (Exception)
{
return false;
}
}
}
}
Este ejemplo verifica si la imagen es una imagen real, y puede modificarla y convertirla.
Se come memoria como un ejemplo de V8 de seis litros, por lo que debe usarse cuando realmente desee saber qué es esta imagen.
en el lado del servidor, compare con el tipo de contenido si coincide con el formato cargado requerido, luego proceda o bien devuelva un mensaje de error