C#Httpclient FormUrlEncodedContent编码

C#Httpclient FormUrlEncodedContent编码,c#,uwp,.net-core,C#,Uwp,.net Core,我遇到了一个使用httpclient将数据发布到服务器的问题。httpclient.PostAsync与FormUrlEncodedContent配合使用效果很好 但是,如果FormUrlEncodedContent的内容包含字符“~”,则不会将其转换为%7E。我不知道怎样才能强迫它编码 下面是我当前的编码示例 var content = new FormUrlEncodedContent(new Dictionary<string, string>() { ["conten

我遇到了一个使用httpclient将数据发布到服务器的问题。httpclient.PostAsync与FormUrlEncodedContent配合使用效果很好

但是,如果FormUrlEncodedContent的内容包含字符“~”,则不会将其转换为%7E。我不知道怎样才能强迫它编码

下面是我当前的编码示例

var content = new FormUrlEncodedContent(new Dictionary<string, string>()
{
    ["content"] = "Hello World~"
});
var response = await httpClient.PostAsync(url, content);
var content=new FormUrlEncodedContent(new Dictionary())
{
[“内容”]=“你好,世界~”
});
var response=wait-httpClient.PostAsync(url、内容);
Fiddler主体内容的原始结果将是:

content=Hello%20World~

这不是我所期望的。我希望结果应该是 content=Hello%20World%7E

我该怎么做


谢谢

这很有趣。所以tilde(~)是非常特别的…如果你看rfc2396和rfc3986,它实际上是允许在URL中使用的。rfc1738将其定义为%7e,但rfc2396和rfc3986有点否决了这一点

所以…这基本上取决于编码实现。例如,PHP在某个时候对其进行了更改:

顺便说一句,在CoreFx回购协议中,您可以查看

正如你所看到的,它使用

它说

默认情况下,EscapeDataString方法转换除 对于RFC 2396,将未保留字符转换为十六进制 代表性

而在tilde中定义为无保留字符

因此,这是根据文档进行的,fiddler向您展示的是一个绝对有效的URL

要获取%7e而不是“~”的特定问题,请执行以下操作: 一种选择是手动更换,因为这确实是一种特殊情况


另一个是使用,它将其编码为%7e。EscapeDataString(FormUrlEncodedContent使用)与System.Web.HttpUtility.UrlEncode之间的区别在于EscapeDataString使用尽可能多的纯文本字符。但它们都创建了一个有效的URL编码字符串

这是一个应该完成工作的变通方法:

        var formParams = new Dictionary<string, string>(){
            ["content"] = "Hello World~"
        };

        var stringFormParams = new Func<IDictionary<string,string>,string>((dic) => {
            string result = "";
            foreach(var param in dic) {
                if (result.Length > 0) { result += "&"; }
                result += param.Key + "=" + WebUtility.UrlEncode(param.Value);
            }   
            return result;             
        }).Invoke(formParams); 

        var stringContent = new StringContent(stringFormParams, Encoding.UTF8, "application/x-www-form-urlencoded");
        Console.WriteLine(stringContent.ReadAsStringAsync().Result);

        HttpClient httpClient = new HttpClient();
        var response = await httpClient.PostAsync(url, stringContent);

因此,您希望使用“System.Web”库中的HttpUtility UrlEncode方法。有关msdn页面,请参阅

System.Web.HttpUtility.UrlEncode(@"~\Hello World");
结果:

%7e%5URL%5Hello+世界


我已经试过并测试过了——它正确地将符号替换为正确编码的对应符号。

@gregkalapos和@Bertie有一个很好的答案

但是我有其他的方法来使用Uri进行编码

Uri.EscapeDataString(str) 
如果您需要unescape,请使用
Uri.UnescapeDataString(str)

见:


谢谢,它很管用。我使用corefx one的源代码并创建自己的类。在编码方法上。我只需要将~替换为%7E
private static string Encode(string data){if(string.IsNullOrEmpty(data)){return string.Empty;}//转义空格为'+'。return Uri.EscapeDataString(data)。Replace(“%20”,“+”)。Replace(“~”,“%7E”);}@Jobria yes,这似乎很好,但如果屏幕上有非英语字符(如汉语或日语),则会出现问题content@Jobria它可以用于汉字和日语,因为我用得很好。我认为这仍然是可行的。然而,我没有测试它。我使用了gregkalapos one的答案。不管怎样,谢谢你的帮助。你是对的-抱歉,我没有看到netcore标签@gregkalapos有一个很好的答案。EscapeDataString本身就可以很好地工作——使用netcore控制台应用程序和netcore web服务进行了尝试。
Uri.EscapeDataString(str)