HttpWebRequest不发送+(加号)字符

Cra*_*ker 3 c# post httpwebrequest

我正在尝试使用POST请求发送base64编码数据,它包含"+"字符.当我发送请求时,"+"被替换为""(空格).这是代码

    public string POST(string url, string query)
    {
        HttpWebRequest hwrq = CreateRequest(url);
        hwrq.CookieContainer = Cookies;
        hwrq.Method = "POST";
        hwrq.ContentType = "application/x-www-form-urlencoded";
        byte[] data = Encoding.Default.GetBytes(query);
        hwrq.ContentLength = data.Length;
        hwrq.GetRequestStream().Write(data, 0, data.Length);
        using (HttpWebResponse hwrs = (HttpWebResponse)hwrq.GetResponse())
        {
            using (StreamReader sr = new StreamReader(hwrs.GetResponseStream()))
            {
                return sr.ReadToEnd().Trim();
            }
        }
    }

    public HttpWebRequest CreateRequest(string url)
    {
        HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(url);
        Request.UserAgent = UserAgent;
        Request.Accept = Accept;
        Request.Headers.Add("Accept-Language", AcceptLang);
        Request.AutomaticDecompression = DMethod;
        return Request;
    }
Run Code Online (Sandbox Code Playgroud)

我一直在跟踪"查询"变量,它保持"+"字符,但当我在嗅探器(Charles)中看到请求时,请求将在没有"+"的情况下发送.
例如,我正在尝试发送

<...> + ZXJ ZZQ <...>

<...> zxJ zZq <...>

实际上是发送.
我究竟做错了什么?
提前致谢.

Dar*_*rov 10

+表示查询字符串中的空格.它看起来像您query发送的变量没有正确的URL编码.遗憾的是,您还没有展示如何构造此query字符串变量,但这是正确的方法,以确保所有值都正确的URL编码:

var values = HttpUtility.ParseQueryString(string.Empty);
values["foo"] = "some + value";
values["bar"] = "some other value";
string query = values.ToString();
// query will equal foo=some+%2b+value&bar=some+other+value
Run Code Online (Sandbox Code Playgroud)

请注意+原始属于该值的符号是如何编码的%2B.

如果你写下面的内容:

string query = "foo=some + value&bar=some other value";
Run Code Online (Sandbox Code Playgroud)

我认为你看到了自己的问题以及正确的查询字符串之间的区别foo=some+%2b+value&bar=some+other+value.

现在这里说的是我建议你改进你的代码.你可以扩展WebClient类,以便它可以处理cookie,如下所示:

public class WebClientEx : WebClient
{
    public CookieContainer Cookies { get; private set; }
    public WebClientEx()
    {
        Cookies = new CookieContainer();
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        var request = (HttpWebRequest)base.GetWebRequest(address);
        request.CookieContainer = Cookies;
        return request;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在简单地说:

using (var client = new WebClientEx())
{
    client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0";
    client.Headers[HttpRequestHeader.AcceptLanguage] = "en-us,en;q=0.5";
    var values = new NameValueCollection
    {
        { "foo", "some value" },
        { "bar", "some & other + value =" },
    };
    byte[] buffer = client.UploadValues("http://www.example.com", values);
    string result = Encoding.UTF8.GetString(buffer);
}
Run Code Online (Sandbox Code Playgroud)

看看这有多容易,而不是乱搞所有那些HttpWebRequests,响应,流,编码等......?