Создание формы загрузки аватара для пользователей

Я использую ASP.Net MVC 5 и я хочу создать аватар для моих профилей пользователей. Я не уверен, что то, что я делаю до сих пор, правильно, особенно по соображениям безопасности, поэтому я хотел получить совет.

что я делаю до сих пор

В Виде:

@using (Html.BeginForm("ManageUser", "Account", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="file" />
    <input type="submit" value="Add Avatar" />
}

в контроллере:

    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;
    }

у меня есть несколько вопросов:

  • в коде выше, как я заметил, я думаю, вместо сохранения что пользователь отправил мне, я должен как-то использовать библиотеку для преобразования изображение в PNG-файл и сохраните его. Если да, то есть ли хорошая и простая библиотека для этого?
  • интересно, было бы неплохо использовать имя пользователя в качестве файла. В конце концов, они выбирают это имя, и это не то, что я решаю.
  • это хорошая идея использовать простые изображения или я должен создать контроллер для проверки запросов или разбить запросы на скрытый изображения?

Если то, что я делаю полностью неправильно и вы знаете, лучший источник, чтобы узнать правильный путь, пожалуйста, мне точку в правильном направлении. Спасибо.

2 ответов


вы можете использовать этот класс для загрузки файла на сервер :

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();
        }

}

вы также можете сохранить эскиз из фотографии, используя ResizeImage метод и в контроллере я сохраню имя файла в базе данных следующим образом:

[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");


 }

также для конвертации загруженных изображений вы можете использовать код внутри UploadFile способ :

    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); 

Я нашел этот пост очень полезным, и я хотел поделиться своей реализацией превосходного ответа Sirwan Afifi. Мне нужна функция изменения размера, чтобы взять и вернуть изображение, так что это немного отличается. Однако я также добавил логическое значение, чтобы сохранить соотношение сторон изображения, если хотите.

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;

    }