2011-12-19 51 views
1

手头问题:以下代码有时会抛出System.ArgumentException: Illegal characters in path正确处理上传文件名称的方式

var fileName = Path.GetFileName(Request.Files[0].FileName); 

文件是由各种最终用户上传的,所以我不能假装这种情况是无效的并忽略它。

UserAgent失败的上传请求通常指向Mac系统。而且,当我打扰调查时,非法角色是0-32范围内的一些控制角色。

GetFileName()呼叫当然是需要的,因为有时HttpPostedFile.FileName只包含文件的名称,有时在用户的机器上包含完整路径。我可以做一些傻事

var fileName = Request.Files[0].FileName; 
foreach (var c in Path.GetInvalidPathChars()) 
    fileName = fileName.Replace(c, '_'); 
fileName = Path.GetFileName(fileName); 

但它只是感觉不对。

是否没有标准的“网络”方式处理上传的文件名?我很难接受我是第一个遇到这个问题的人。

============================================== ====================

为了避免进一步的混淆。提取的文件名是而不是用于存储磁盘上的文件,并且不必在托管环境的上下文中有效。它只需要显示回给用户。

+0

我相信标准的方法是在服务器上生成一个与其他用户上传文件不冲突的文件名。 – dtb 2011-12-19 14:33:18

+0

通常不是一个标准,但我会说什么更建议比什么不是。例如用数字1,2,3等起始名称也要记住,你应该知道文件可以处理或不处理关于命名文件的事情。我将创建一个Validation类并检查字符'!,@, #,$,%,^,&,*,(,),+,=,{,},[,]你会得到这个想法..创建一个无效的字符或字符串,只允许“_”或“ - '和第一个字符之后的数字......你有什么东西在顶部是好的,但你只是检查'_'下划线所有其他命名约定将通过 – MethodMan 2011-12-19 14:36:22

+0

@dtb文件存储在磁盘上, Guid.NewGuid()的ToString( “N”)'。仍然需要向用户提供原始名称,我需要以某种方式进行解析。 – 2011-12-19 14:36:24

回答

1

只是替换字符是不安全的。您应该验证文件名并提示用户在不支持时修复它(这是完全合法的,即使您的操作系统对文件名也有限制)。 否则,您可以:

  1. 如你所说,替换不支持字符(但你怎么能保证你更换了所有可能的无效字符?)
  2. 编码的文件名
+0

似乎不是一个可行的解决方法...我要告诉他们什么?请从路径名称中删除字符代码X? – 2011-12-19 14:47:18

1

如果你只是想显示用户提交的文件名并且不一定需要有效的文件名,您可以剥去任何字符直到最后一个/或\字符:

string result = name.Substring(name.LastIndexOfAny(new[] { '/', '\\' }) + 1); 

LastIndexOfAny返回-1,如果没有/或\被发现,所以原始的字符串在这种情况下返回。)

不要忘记它显示给用户时,HTML编码的文件名。

+0

+1这是可行的,虽然不完善。 – 2011-12-19 15:17:05

-1

我通常将DateTime.Now.Ticks添加到文件名或用户ID(和蜱)的开头,然后我可以根据这些详细信息处理/移动文件。

是否有可能导致问题的字符是a。 (我不确定Windows在一个文件名开头处理得非常好