【问题标题】:C# Escape Plus Sign (+) in POST using HttpWebRequestC# Escape 加号 (+) 在 POST 中使用 HttpWebRequest
【发布时间】:2011-12-15 09:03:11
【问题描述】:

我在发送密码字段中包含“+”等字符的 POST 数据时遇到问题,

string postData = String.Format("username={0}&password={1}", "anyname", "+13Gt2");

我正在使用 HttpWebRequest 和网络浏览器查看结果,当我尝试使用 HttpWebRequest 从我的 C# WinForms 登录 将数据发布到网站时,它告诉我密码不正确. (在源代码 [richTexbox1] 和 webBrowser1 中)。用我的另一个帐户尝试它,它不包含“+”字符,它可以让我正确登录(使用字节数组并将其写入流)

byte[] byteArray = Encoding.ASCII.GetBytes(postData); //get the data
request.Method = "POST"; 
request.Accept = "text/html";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
newStream.Close(); //this works well if user does not includes symbols

Question我发现HttpUtility.UrlEncode()是转义非法字符的解决方案,但我不知道如何正确使用它,我的问题是,在使用urlEncode()对我的POST数据进行url编码后如何正确地将数据发送到我的请求

这就是我一直在尝试 HOURS 使其工作的方法,但没有运气,

第一种方法

string urlEncoded = HttpUtility.UrlEncode(postData, ASCIIEncoding.ASCII);
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = urlEncoded.Length;
StreamWriter wr = new StreamWriter(request.GetRequestStream(),ASCIIEncoding.ASCII);
wr.Write(urlEncoded); //server returns for wrong password.
wr.Close();

第二种方法

byte[] urlEncodedArray = HttpUtility.UrlEncodeToBytes(postData,ASCIIEncoding.ASCII);
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(urlEncodedArray, 0, urlEncodedArray.Length); // Send the data.
newStream.Close();  //The server tells me the same thing..

我认为我在必须如何将 url 编码发送到请求方面做错了,我真的请求帮助,我通过谷歌搜索并找不到有关如何将编码的 url 发送到的更多信息HttpWebRequest.. 感谢您的时间和关注,希望您能帮助我。谢谢。

【问题讨论】:

  • 您不必对发布数据进行编码。事实上,当你像这样对发布数据进行编码时,浏览器会错误地解释它。您的编码可能有问题。将 charset=ISO-8859-1 添加到您的内容类型,看看会发生什么
  • @Polity 首先感谢你让我明白,我找不到如何使用 urlEncode 来转义特殊字符,我试过你告诉我的(charset=ISO-8859-1)并且仍然有相同的结果,没有任何改变,我相信它在编码上,'+'被转换为空格。

标签: c# winforms post httpwebrequest urlencode


【解决方案1】:

我使用Uri.EscapeDataString 找到了我的答案,它完全解决了我的问题,但不知何故我无法使用HttpUtility.UrlEncode 做到这一点。 Stackoverflowing 周围,我发现这个 question 是关于 urlEncode 方法的,在 msdn 中它的文档告诉:

对 URL 字符串进行编码。

但我现在知道如果用于编码 POST 数据是错误的(@Marvin,@Polity,感谢您的更正)。丢弃后,我尝试了以下方法:

string postData = String.Format("username={0}&password={1}", "anyname", Uri.EscapeDataString("+13Gt2"));

POST数据转换成:

// **Output
string username = anyname;
string password = %2B13Gt2;

Uri.EscapeDataStringmsdn 中表示以下内容:

将字符串转换为其转义表示。

我认为这就是我一直在寻找的东西,当我尝试上述方法时,只要表单数据中有包含“+”字符的数据,我就可以正确 POST,但不知何故,还有很多东西要学习。

这个链接真的很有帮助。

http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx

非常感谢您的回答和您的时间,非常感谢。问候队友。

【讨论】:

    【解决方案2】:

    我建议您使用WebClient。将缩短您的代码并处理编码和其他内容:

    using (var client = new WebClient())
    {
        var values = new NameValueCollection
        { 
            { "username", "anyname" },
            { "password", "+13Gt2" },
        };
        var url = "http://foo.com";
        var result = client.UploadValues(url, values);
    }
    

    【讨论】:

    • 感谢@Darin,但不幸的是该网站不支持WebClient,所以每当我这样做时,我都会得到“不支持此浏览器”但是有趣的是使用WebClient时不需要设置编码,但我会尝试在传递“+”字符时是否可行。我已经使用Uri.EscapeDataString 找到了我的答案,非常感谢您提供的有用答案。
    • @WhySoSerious,网站不知道 WebClient 是什么。网站侦听并回答 HTTP 请求。 WebClient 可以发送 HTTP 请求。因此,如果站点说不支持浏览器,则该站点可能希望在请求中设置一些特殊的 User-Agent 标头。因此,只需使用 Headers 属性并将 User-Agent HTTP 请求标头设置为您尝试访问的站点所期望的任何内容。
    【解决方案3】:

    您发送的 postdata 不应该是 URL 编码的!它是表单数据,而不是 URL

      string url = @"http://localhost/WebApp/AddService.asmx/Add";
      string postData = "x=6&y=8";
    
      WebRequest req = WebRequest.Create(url);
      HttpWebRequest httpReq = (HttpWebRequest)req;
    
      httpReq.Method = WebRequestMethods.Http.Post;
      httpReq.ContentType = "application/x-www-form-urlencoded";
      Stream s = httpReq.GetRequestStream();
      StreamWriter sw = new StreamWriter(s,Encoding.ASCII);
      sw.Write(postData);
      sw.Close();
    
      HttpWebResponse httpResp = 
                     (HttpWebResponse)httpReq.GetResponse();
      s = httpResp.GetResponseStream();
      StreamReader sr = new StreamReader(s, Encoding.ASCII);
      Console.WriteLine(sr.ReadToEnd());
    

    这使用 System.Text.Encoding.ASCII 对 postdata 进行编码。

    希望这会有所帮助,

    【讨论】:

    • 这要么不能解决问题,要么会引入更多错误。请参阅:w3.org/TR/REC-html40/charset.html#h-5.2.2 HTML 中没有隐含编码,HTTP 暗示 ISO-8859-1 作为默认编码,而不是 ASCII(首先它甚至不是编码,问 skeet ;))
    • 嗨@Marvin,谢谢你的回答,但这是我在我的代码上所做的,这仍然没有转义'+'字符,看到我用StreamWriter和ASCII一起使用它尝试“编码”postData时的编码,这是错误的(从你们那里知道),感谢您抽出宝贵的时间来回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    相关资源
    最近更新 更多