我有一个应用程序,发送一个POST请求到VB论坛软件,并登录某人(没有设置cookie或任何东西)。

一旦用户登录,我就创建一个变量,在他们的本地机器上创建一个路径。

c: \用户tempfolder枣\

问题是一些用户名抛出“非法字符”异常。例如,如果我的用户名是mas|fenix,它会抛出一个异常。

Path.Combine( _      
  Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
  DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)

我不想从字符串中删除它,但是通过FTP在服务器上创建了一个具有其用户名的文件夹。这就引出了我的第二个问题。如果我在服务器上创建一个文件夹,我可以留下“非法字符”吗?我问这个问题是因为服务器是基于Linux的,我不确定Linux是否接受它。

编辑:似乎URL编码不是我想要的..这就是我想做的:

old username = mas|fenix
new username = mas%xxfenix

其中%xx是ASCII值或任何其他容易识别字符的值。


当前回答

Ideally these would go in a class called "FileNaming" or maybe just rename Encode to "FileNameEncode". Note: these are not designed to handle Full Paths, just the folder and/or file names. Ideally you would Split("/") your full path first and then check the pieces. And obviously instead of a union, you could just add the "%" character to the list of chars not allowed in Windows, but I think it's more helpful/readable/factual this way. Decode() is exactly the same but switches the Replace(Uri.HexEscape(s[0]), s) "escaped" with the character.

public static List<string> urlEncodedCharacters = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "%" //and others, but not *
};
//Since this is a superset of urlEncodedCharacters, we won't be able to only use UrlEncode() - instead we'll use HexEncode
public static List<string> specialCharactersNotAllowedInWindows = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "*" //windows dissallowed character set
};

    public static string Encode(string fileName)
    {
        //CheckForFullPath(fileName); // optional: make sure it's not a path?
        List<string> charactersToChange = new List<string>(specialCharactersNotAllowedInWindows);
        charactersToChange.AddRange(urlEncodedCharacters.
            Where(x => !urlEncodedCharacters.Union(specialCharactersNotAllowedInWindows).Contains(x)));   // add any non duplicates (%)

        charactersToChange.ForEach(s => fileName = fileName.Replace(s, Uri.HexEscape(s[0])));   // "?" => "%3f"

        return fileName;
    }

感谢@simon-tewsi提供的非常有用的表格!

其他回答

您应该只对用户名或URL中可能无效的其他部分进行编码。URL编码URL可能会导致这样的问题:

string url = HttpUtility.UrlEncode("http://www.google.com/search?q=Example");

将产生

http 3a % 2f 2fwww。google。com % 2fsearch 3fq % 3dExample

这显然不会有很好的效果。相反,你应该在查询字符串中只编码键/值对的值,就像这样:

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");

希望这有帮助。另外,正如teedyay提到的,您仍然需要确保非法文件名字符被删除,否则文件系统将不喜欢该路径。

编辑:注意,这个答案现在已经过时了。请参阅下面Siarhei Kuchuk的答案以获得更好的解决方案

UrlEncoding会做你在这里建议的事情。对于c#,您只需使用HttpUtility,如前所述。

您还可以Regex非法字符,然后进行替换,但这变得更加复杂,因为您必须有某种形式的状态机(switch…用正确的字符替换。由于UrlEncode预先完成了这个操作,所以相当简单。

至于Linux和windows,有一些字符在Linux中是可以接受的,但在windows中是不可以接受的,但我并不担心这一点,因为文件夹名可以通过解码Url字符串返回,使用UrlDecode,因此您可以往返更改。

对于。net核心用户,使用这个

Microsoft.AspNetCore.Http.Extensions.UriHelper.Encode(Uri uri)

更好的方法是使用

Uri。EscapeUriString

不引用。net 4的完整配置文件。

(更新)

根据OP的要求,推荐的API应该是

Uri。EscapeDataString

(谢谢@ykadaru)

Ideally these would go in a class called "FileNaming" or maybe just rename Encode to "FileNameEncode". Note: these are not designed to handle Full Paths, just the folder and/or file names. Ideally you would Split("/") your full path first and then check the pieces. And obviously instead of a union, you could just add the "%" character to the list of chars not allowed in Windows, but I think it's more helpful/readable/factual this way. Decode() is exactly the same but switches the Replace(Uri.HexEscape(s[0]), s) "escaped" with the character.

public static List<string> urlEncodedCharacters = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "%" //and others, but not *
};
//Since this is a superset of urlEncodedCharacters, we won't be able to only use UrlEncode() - instead we'll use HexEncode
public static List<string> specialCharactersNotAllowedInWindows = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "*" //windows dissallowed character set
};

    public static string Encode(string fileName)
    {
        //CheckForFullPath(fileName); // optional: make sure it's not a path?
        List<string> charactersToChange = new List<string>(specialCharactersNotAllowedInWindows);
        charactersToChange.AddRange(urlEncodedCharacters.
            Where(x => !urlEncodedCharacters.Union(specialCharactersNotAllowedInWindows).Contains(x)));   // add any non duplicates (%)

        charactersToChange.ForEach(s => fileName = fileName.Replace(s, Uri.HexEscape(s[0])));   // "?" => "%3f"

        return fileName;
    }

感谢@simon-tewsi提供的非常有用的表格!