C# 正确处理上传文件名称的方法

C# 正确处理上传文件名称的方法,c#,asp.net,.net,C#,Asp.net,.net,当前问题:以下代码有时抛出系统。ArgumentException:路径中的非法字符 var fileName = Path.GetFileName(Request.Files[0].FileName); 文件是由不同的最终用户上传的,所以我不能假装这个案例无效而忽略它 失败上传请求的UserAgent字符串通常指向Mac系统。非法字符(在我费心调查的情况下)是0-32范围内的一些控制字符 当然需要调用GetFileName(),因为有时候HttpPostedFile.FileName只包含文

当前问题:以下代码有时抛出
系统。ArgumentException:路径中的非法字符

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);
但感觉不太对劲

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

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


以避免进一步混淆。提取的文件名不用于将文件存储在磁盘上,并且在托管环境的上下文中不必有效。只需将其显示回用户即可。

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

  • 正如您所说的,替换不支持的字符(但是如何确保替换所有可能的无效字符?)
  • 对文件名进行编码

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

  • 正如您所说的,替换不支持的字符(但是如何确保替换所有可能的无效字符?)
  • 对文件名进行编码

  • 如果您只想显示用户提交的文件名,而不一定需要有效的文件名,则只需去掉最后一个/或\字符:

    string result = name.Substring(name.LastIndexOfAny(new[] { '/', '\\' }) + 1);
    
    (如果未找到/或\则LastIndexOfAny返回-1,因此在本例中返回原始字符串。)


    向用户显示文件名时,不要忘记对文件名进行HTML编码。

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

    string result = name.Substring(name.LastIndexOfAny(new[] { '/', '\\' }) + 1);
    
    (如果未找到/或\则LastIndexOfAny返回-1,因此在本例中返回原始字符串。)


    在向用户显示文件名时,不要忘记对文件名进行HTML编码。

    我通常会在文件名或用户ID(和记号)的开头添加DateTime.Now.Ticks,然后我可以根据这些细节处理/移动文件


    导致问题的角色是否可能是一个角色。(我不确定windows是否能很好地处理。在文件名的开头

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


    导致问题的角色是否可能是一个角色。(我不确定windows是否能很好地处理文件名。在文件名的开头

    我认为标准的方法是在服务器上生成一个与其他用户上传的文件不冲突的文件名。这通常不是标准,但我会说什么更推荐,什么不推荐。。例如,以数字1、2、3等开头的名称也可以保留。)请记住,您应该知道文件在命名文件时可以处理或不可以处理的内容。我将创建一个验证类,并检查字符“!”、@、#、$、%、^、&、*、(,)、+、=、{、}、[,]您明白了。创建一个无效字符或字符串数组,并且只允许“”或者在第一个字符后面加上“-”和数字…你在上面加的是好的,但是你只检查“”下划线,所有其他的命名约定都可以thru@dtb文件存储在磁盘上,其名称由
    Guid.NewGuid().ToString(“n”)生成
    。我仍然需要向用户提供原始名称,我需要以某种方式对其进行解析。您还可以格式化文件名string.format(DateTime.Now.ToString(“\u mmddyyyhhmmss”))+将用户域名添加到文件GUID中也很有效,但是如果用户必须访问该文件,那么看起来会很有趣。为什么不用原始名称对GUID进行后缀?或者将GUID和原始名称之间的关系存储在数据库中?我相信标准的方法是在与其他用户上传的文件不冲突的服务器。这通常不是一个标准,但我会说什么是更推荐的,什么不是。例如,以数字1、2、3等开头的名称也要记住,在命名文件时,您应该知道文件可以处理或不可以处理的事情。我将创建一个验证类并检查f或者字符“!,@,#,$,%,^,&,*,(,),+,=,{,},[,]你明白了。创建一个无效字符或字符串数组,只允许“”或者在第一个字符后面加上“-”和数字…你在上面加的是好的,但是你只检查“”下划线,所有其他的命名约定都可以thru@dtb文件存储在磁盘上,其名称由
    Guid.NewGuid().ToString(“n”)生成
    。我仍然需要向用户提供原始名称,我需要以某种方式对其进行解析。您还可以格式化文件名string.format(DateTime.Now.ToString(“\u mmddyyyhhmmss”))+将用户域名添加到文件GUID中也很有效,但是如果用户必须访问该文件,那么看起来会很有趣。为什么不用原始名称对GUID进行后缀?或者将GUID和原始名称之间的关系存储在数据库中?这似乎不是一个可行的解决方法…我该怎么办告诉他们?请从您的路径名中删除字符代码X?这似乎不是可行的wo