文件上传:要保存的文件名称应该是什么?

时间:2009-07-24 08:41:44

标签: asp.net file-upload

我要将文件上传控件添加到我的ASP.NET 2.0网页,以便用户可以上传文件。文件将存储在服务器中,文件名为用户名。我想知道保存到服务器时命名文件的最佳选项是什么。需要考虑安全性,性能,灵活性来处理文件等。如果我错过任何内容,请指导我

我正在考虑的选项:

  1. 使用与输入文件名相同的名称上传
  2. 添加用户ID +随机数+文件名作为输入文件名
  3. 以秒为单位创建随机数+当前时间并使用该数字保存文件。将有一个表来映射此号码与用户上传
  4. 还有别的吗?什么是最好的方式?

    提前致谢

5 个答案:

答案 0 :(得分:5)

永远不要将用户输入用于文件名。不要使用用户名。请改为使用用户ID(我假设您的用户拥有唯一ID)。

永远不要使用原始文件名。使用您的解决方案编号3,加上用户ID而不是用户名。

为了您的信息,几年前PHP有一个漏洞:一个可以伪造一个带文件上传的HTTP POST请求,文件名如“../../anything.php”,以及php _FILES数组,应该包含已清理的值,但没有检测到这些文件名,因此可以在文件系统中的任何位置写入文件。

答案 1 :(得分:2)

我会使用

的组合
  • 用户ID
  • 随机生成的字符串(例如GUID)

示例PDF文件名:23212-dd503cf8-a548-4584-a0a3-39dc8be618df.pdf

这样,用户可以上传他/她想要的文件,而不会发生文件名冲突,只需查看文件名,您就可以指出哪些文件属于哪些用户。

我认为不需要在文件名中包含任何其他信息,因为可以从文件的属性中检索上传时间/日期等。

此外,您应将文件存储在安全的位置,外部用户(例如您网站的访问者)无法访问这些文件。相反,您通过代理网页将文件传递给它们(您从安全位置读取文件,并将数据传递给用户)。对于此解决方案,需要一个数据库来跟踪文件,它们的位置等。

这也使您能够通过代码控制哪些用户可以访问哪些文件。


更新:以下是有关如何实施代理网页解决方案的说明。

  1. 创建名为GetFile.aspx
  2. 的网络表单
  3. GetFile.aspx接受一个名为fileid的查询参数,该参数用于标识要获取的文件。例如:
    http://www.mypage.com/GetFile.aspx?fileid=100
  4. 使用fileid参数查找数据库中的文件位置,以便可以读取并发送给用户。在Web窗体中,使用Request.QueryString("fileid")获取文件ID,并在查询中使用它(SQL):
    SELECT FileLocation FROM UserFiles WHERE FileID = 100
  5. 使用System.IO.FileStream读取文件,并通过Response.Write输出其内容。请务必先使用Response.ContentType设置相应的content type,以便客户端浏览器正确处理所请求的文件(请参阅asp.forums.net上的this postMDSN article也在帖子中提到,它们都讨论了一种自动确定适当内容类型的方法。
  6. 如果选择此方法,以后可以轻松实现自己的简单安全或自定义操作,例如确保用户在发送文件之前登录到您的网站,或者用户只能访问他们上传的文件他们自己,或记录用户下载哪些文件等。可能性是无穷无尽的; - )

答案 2 :(得分:1)

查看System.IO.Path class因为它有许多有用的功能,例如:

检查文件名中哪些字符无效:

System.IO.Path.GetInvalidPathChars();

获取随机文件名:

System.IO.Path.GetRandomFileName();

在临时目录中获取唯一的randome文件名

System.IO.Path.GetTempFileName();

答案 3 :(得分:0)

我会选择#3选项。将这些文件映射到用户的表格将提供其他用途,它始终如此。如果使用映射,则在尝试调试问题时,将用户名或ID附加到文件的唯一优势是。

我可能会使用GUID而不是随机数,但两者都可以使用。我认为重要的事情是

  1. 作为文件名的一部分,没有用户名作为存储文件的任何部分
  2. 切勿将原始文件名用作存储文件的任何部分
  3. 使用随机数或GUID确保没有重复文件
  4. 向文件添加用户ID有助于解决手动调试问题

答案 4 :(得分:0)

除此之外还有更多的事情......我想你已经知道了!

你在谈论什么样的文件?如果它们甚至是远程大或数量太大以至于文件组可能很大,我会立即建议你为你的方法增加一些灵活性。

  1. 创建一个表,用于存储各种文件存储的根路径(这可以是驱动器,非路径,您的环境支持的内容)。它最初将有一个条目,它将是您的第一个存储位置。使用此数据维护的一个很好的属性是这里可以存储多少空间。
  2. 维护一个文件相关数据表(id {guid},创建日期,路径数据的外键,文件大小)
  3. 将文件写入仍然有空间的根(查询存储在根位置的所有文件大小并与根容量进行比较)
  4. 使用名称的GUID编写文件(对文件系统上的文件进行模糊处理)..如果安全性需要,可以编写没有文件扩展名的文件(敏感文件)
  5. 根据创建日期从根/年{number} / month {number} / day {number} /file.extension
  6. 开始编写文件

    使用这种性质的系统 - 即使您不需要/不需要它 - 您现在可以更轻松地重新定位文件。您可以更好地管理文件。您可以更好地管理文件集合。等我以前使用过这个系统,发现它非常灵活。处理存储到文件系统但是从数据库管理的文件,一旦文件存储变得如此之大并且需要稍微移动一些东西,就会有点失控。此外,至少在Windows的情况下......在一个目录中存储数以万计的文件通常不是一个好主意(根据创建日期分解的原因)。

    只有当您拥有大量和大尺寸的足迹时,才真正需要这种复杂性。