【问题标题】:Create an avatar upload form for users为用户创建头像上传表单
【发布时间】:2013-09-05 09:11:30
【问题描述】:

我正在使用 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 文件并保存。如果是这样,是否有一个好的和简单的库来做到这一点?
  • 我想知道使用用户名作为文件是否是个好主意。毕竟,他们选择了这个名字,这不是我决定的。
  • 使用普通图像是个好主意,还是应该创建一个控制器来验证请求或将请求路由到隐藏图像?

如果我的操作完全错了,并且您知道更好的资源来学习正确的方法,请指出我正确的方向。谢谢。

【问题讨论】:

  • 我唯一看到的缺失是您应该验证服务器端该文件确实是一个图像(这样做客户端听起来不是一个好主意)。请参阅该答案here。除了以一致的格式保存头像是个好主意,PNG 是一种很好的格式,Image 类知道如何做到这一点。
  • 好吧,我会使用用户 ID(如果你知道的话)而不是用户名(文件命名约定!= 用户名约定)。或者只是将 db 中的头像保存为表用户字段。您还可以强制用户仅上传有限的图像类型(仅 png,或仅您知道如何转换为 png 的格式)
  • @AlirezaNoori 类似的东西是的,很长时间没有处理图像,如果文件不是图像,它会给你一个异常,如果是,你可以检查大小、格式等
  • @SimonRapilly 好的。谢谢你。我正在执行你提到的帖子所说的内容。
  • @AlirezaNoori ,哦顺便说一句,阅读我链接的答案以及您对文件名的问题,让我想到了图像的大小(而不是文件的大小),你需要以多种尺寸显示头像?如果是这样,做法往往是将头像保存为多种尺寸,然后加载合适的尺寸进行显示。即使您需要单一尺寸,在保存之前调整图像大小也是一个不错的选择(节省空间,并且避免每次需要显示头像时都必须调整头像)

标签: c# asp.net asp.net-mvc asp.net-mvc-5


【解决方案1】:

您可以使用此类将文件上传到服务器:

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 方法中使用this code 来转换上传的图像:

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

【讨论】:

    【解决方案2】:

    我发现这篇文章很有帮助,我想分享我对 Sirwan Afifi 出色答案的实施。我需要 resize 函数来获取和返回图像,所以它有点不同。但是,如果您愿意,我还添加了一个布尔值来保留图像的纵横比。

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

    【讨论】:

      猜你喜欢
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      • 2013-10-31
      相关资源
      最近更新 更多