我有一个应用程序,发送一个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值或任何其他容易识别字符的值。


当前回答

Url编码在。net中很容易。使用:

System.Web.HttpUtility.UrlEncode(string url)

如果要对其进行解码以获得文件夹名称,则仍然需要排除文件夹名称中不能使用的字符(*、?、/等)。

其他回答

除了@丹·赫伯特的回答, 我们应该对一般的值进行编码。

Split有参数Split('&','=');表达式首先被&分割,然后是'=',因此奇数元素都是要编码的值,如下所示。

public static void EncodeQueryString(ref string queryString)
{
    var array=queryString.Split('&','=');
    for (int i = 0; i < array.Length; i++) {
        string part=array[i];
        if(i%2==1)
        {               
            part=System.Web.HttpUtility.UrlEncode(array[i]);
            queryString=queryString.Replace(array[i],part);
        }
    }
}

UrlEncode的. net实现不符合RFC 3986。

Some characters are not encoded but should be. The !()* characters are listed in the RFC's section 2.2 as a reserved characters that must be encoded yet .NET fails to encode these characters. Some characters are encoded but should not be. The .-_ characters are not listed in the RFC's section 2.2 as a reserved character that should not be encoded yet .NET erroneously encodes these characters. The RFC specifies that to be consistent, implementations should use upper-case HEXDIG, where .NET produces lower-case HEXDIG.

如果你看不见系统。Web,更改项目设置。目标框架应该是。NET Framework 4“代替”。NET Framework 4客户端配置文件

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提供的非常有用的表格!

从。net Framework 4.5和。net Standard 1.0开始,你应该使用WebUtility.UrlEncode。相对于其他选择的优势:

It is part of .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ and all Xamarin platforms as well. HttpUtility, while being available in .NET Framework earlier (.NET Framework 1.1+), becomes available on other platforms much later (.NET Core 2.0+, .NET Standard 2.0+) and it still unavailable in UWP (see related question). In .NET Framework, it resides in System.dll, so it does not require any additional references, unlike HttpUtility. It properly escapes characters for URLs, unlike Uri.EscapeUriString (see comments to drweb86's answer). It does not have any limits on the length of the string, unlike Uri.EscapeDataString (see related question), so it can be used for POST requests, for example.