I’m using ASP.Net MVC 5 and I want to create an avatar for my user profiles. I’m not sure if what I’m doing so far is the right way, especially for security reasons so I wanted to get some advice.
What I’m doing so far
In View:
@using (Html.BeginForm("ManageUser", "Account", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="Add Avatar" />
}
In controller:
internal static bool SaveAvatar(User user, HttpPostedFileBase file)
{
if (file == null || file.ContentLength <= 0 || file.ContentLength > MAX_LENGTH)
return false;
//I think I should convert the file somehow instead of saving it
var path = HostingEnvironment.MapPath("~/img/avatar/") + string.Format("{0}.png", user.UserName);
file.SaveAs(path);
user.HasAvatar = true;
return true;
}
I have several concerns:
- In the code above, as I commented, I think instead of just saving
what user has sent to me, I should somehow use a library to convert
the image to a PNG file and save it. If so, is there a good and simple library to do this? - I wonder whether using the user’s name as a file would be good idea. After all, they choose this name and it is not something I decide.
- Is it a good idea to use plain images or should I create a controller to validate requests or rout the requests to a hidden image?
If what I’m doing is TOTALLY wrong and you know a better source to learn the right way, please point me in the right direction. Thanks.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
you can use this class for Upload a file to server :
public static class FileUpload
{
public static char DirSeparator = System.IO.Path.DirectorySeparatorChar;
public static string FilesPath = HttpContext.Current.Server.MapPath("~\Content" + DirSeparator + "Uploads" + DirSeparator);
public static string UploadFile(HttpPostedFileBase file)
{
// Check if we have a file
if (null == file) return "";
// Make sure the file has content
if (!(file.ContentLength > 0)) return "";
string fileName =DateTime.Now.Millisecond+ file.FileName;
string fileExt = Path.GetExtension(file.FileName);
// Make sure we were able to determine a proper extension
if (null == fileExt) return "";
// Check if the directory we are saving to exists
if (!Directory.Exists(FilesPath))
{
// If it doesn't exist, create the directory
Directory.CreateDirectory(FilesPath);
}
// Set our full path for saving
string path = FilesPath + DirSeparator + fileName;
// Save our file
file.SaveAs(Path.GetFullPath(path));
// Save our thumbnail as well
ResizeImage(file, 70, 70);
// Return the filename
return fileName;
}
public static void DeleteFile(string fileName)
{
// Don't do anything if there is no name
if (fileName.Length == 0) return;
// Set our full path for deleting
string path = FilesPath + DirSeparator + fileName;
string thumbPath = FilesPath + DirSeparator + "Thumbnails" + DirSeparator + fileName;
RemoveFile(path);
RemoveFile(thumbPath);
}
private static void RemoveFile(string path)
{
// Check if our file exists
if (File.Exists(Path.GetFullPath(path)))
{
// Delete our file
File.Delete(Path.GetFullPath(path));
}
}
public static void ResizeImage(HttpPostedFileBase file, int width, int height)
{
string thumbnailDirectory = String.Format(@"{0}{1}{2}", FilesPath, DirSeparator, "Thumbnails");
// Check if the directory we are saving to exists
if (!Directory.Exists(thumbnailDirectory))
{
// If it doesn't exist, create the directory
Directory.CreateDirectory(thumbnailDirectory);
}
// Final path we will save our thumbnail
string imagePath = String.Format(@"{0}{1}{2}", thumbnailDirectory, DirSeparator, file.FileName);
// Create a stream to save the file to when we're done resizing
FileStream stream = new FileStream(Path.GetFullPath(imagePath), FileMode.OpenOrCreate);
// Convert our uploaded file to an image
Image OrigImage = Image.FromStream(file.InputStream);
// Create a new bitmap with the size of our thumbnail
Bitmap TempBitmap = new Bitmap(width, height);
// Create a new image that contains are quality information
Graphics NewImage = Graphics.FromImage(TempBitmap);
NewImage.CompositingQuality = CompositingQuality.HighQuality;
NewImage.SmoothingMode = SmoothingMode.HighQuality;
NewImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Create a rectangle and draw the image
Rectangle imageRectangle = new Rectangle(0, 0, width, height);
NewImage.DrawImage(OrigImage, imageRectangle);
// Save the final file
TempBitmap.Save(stream, OrigImage.RawFormat);
// Clean up the resources
NewImage.Dispose();
TempBitmap.Dispose();
OrigImage.Dispose();
stream.Close();
stream.Dispose();
}
}
you can also save the thumbnail of their photos using ResizeImage method and In the controller I’ll save file name in the database this way:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(User user, HttpPostedFileBase file)
{
// TODO: Add insert logic here
user.Pictuer = FileUpload.UploadFile(file);
db.User.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
also for convert uploaded images you can use this code inside UploadFile method :
System.Drawing.Image image1 = System.Drawing.Image.FromFile(@"C:test.bmp");
// Save the image in JPEG format.
image1.Save(@"C:test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
// Save the image in GIF format.
image1.Save(@"C:test.gif", System.Drawing.Imaging.ImageFormat.Gif);
// Save the image in PNG format.
image1.Save(@"C:test.png", System.Drawing.Imaging.ImageFormat.Png);
Method 2
I found this post very helpful and I wanted to share my implementation of Sirwan Afifi’s excellent answer. I needed the resize function to take and return an image so it’s a little different. However I’ve also added a boolean to preserve the aspect ratio of an image if you want.
public static Image ResizeImage(Image img, int width, int height, bool preserveAspectRatio = false)
{
int newWidth;
int newHeight;
if (preserveAspectRatio)
{
int originalWidth = img.Width;
int originalHeight = img.Height;
float percentWidth = (float)width / (float)originalWidth;
float percentHeight = (float)height / (float)originalHeight;
float percent = percentHeight < percentWidth ? percentHeight : percentWidth;
//Rounding to get the set width to the exact pixel
newWidth = (float)originalWidth * percent < (float)width ? (int)(Math.Ceiling((float)originalWidth * percent)) : (int)((float)originalWidth * percent);
//Rounding to get the set height to the exact pixel
newHeight = (float)originalHeight * percent < (float)height ? (int)(Math.Ceiling((float)originalHeight * percent)) : (int)((float)originalHeight * percent);
}
else
{
newWidth = width;
newHeight = height;
}
// Create a new bitmap with the size
Bitmap TempBitmap = new Bitmap(newWidth, newHeight);
// Create a new image that contains are quality information
Graphics NewImage = Graphics.FromImage(TempBitmap);
NewImage.CompositingQuality = CompositingQuality.HighQuality;
NewImage.SmoothingMode = SmoothingMode.HighQuality;
NewImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Create a rectangle and draw the image
Rectangle imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
NewImage.DrawImage(img, imageRectangle);
return TempBitmap;
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0