重试POST请求会丢失正文c#winforms

时间:2013-11-11 01:07:38

标签: c# winforms

我面临的问题是,在重试请求后,我的POST数据以某种方式丢失了。 代码示例如下。 (请注意,request.timeout = 1设置用于测试目的,以重现下面代码中显示的行为):

//post_data_final getting

private void request_3()
    {
        for(int i=1; i<=5; i++)
        {
            byte[] byteArray = Encoding.ASCII.GetBytes(post_data_final);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site_URI);
            request.Method = "POST";
            //some headers info
            request.Timeout = 1;
            request.ContentLength = byteArray.Length;
            using (Stream os = request.GetRequestStream())
            {
                os.Write(byteArray, 0, byteArray.Length);
            }
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                //some code about response
            }
            catch (WebException wex) 
            {
                if (wex.Status == WebExceptionStatus.Timeout)
                {
                    continue;
                }
                //some additional checks
            }
        }
    }

神奇的是第一个请求(直到请求超时错误)顺利进行。进一步的请求是没有 POST数据,但内容长度被正确计算(即保持与先前请求相同)。


更新:

  1. post_data_final获取是单独的功能。它不被使用(除了byteArray)或在request_3()函数中被更改。
  2. 如果请求进入for循环并且没有发生超时异常,则请求正常。因此,如果我将请求放入for循环,它将执行特定数量的有效请求。一旦我收到Timeout异常,下一个请求就会没有POST数据。
  3. 为那些认为递归是个坏主意的人编辑源代码。编辑后的代码仍无效。
  4. 感谢任何建议

2 个答案:

答案 0 :(得分:0)

我无法在您的代码中发现任何错误,因此请提供模式详细信息,如上所述。

private void request_3()
{
    bool sendData = true;
    int numberOfTimeOuts = 0;

    // The follwing only needs to be done only once, unless you alter post_data_final after each timeout.
    byte[] dataToSend = Encoding.ASCII.GetBytes(post_data_final);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site_URI);
    using (Stream outputStream = request.GetRequestStream())
        outputStream.Write(dataToSend, 0, dataToSend.Length);



    // request.TimeOut = 1000 * 15; would mean 15 Seconds.

    while(sendData && numberOfTimeOuts < MAX_NUMBER_OF_TIMEOUTS)
    {
         try
         {
             HttpWebResponse response = (HttpWebResponse)request.GetResponse();
             if(response != null)
                 processResponse(response);
             else
             {
                 //You should handle this case aswell.
             }

             sendData = false;
         }
         catch(WebException wex)
         {
             if (wex.Status == WebExceptionStatus.Timeout)
                 numberOfTimeOuts++;
             else
                 throw;
         }
    }
}

答案 1 :(得分:0)

问题是因为使用了Fiddler2 - Wireshark的模拟(即拦截交通工具)。

请求的站点使用https协议。出于调试目的,我安装了Fiddler2和Fiddler2证书,以便能够查看所有传入和传出的响应。出于某些神奇的原因,当我关闭Fiddler2并在控制台中添加了一些额外的日志记录时,我发现请求似乎是有效的(即POST主体数据在第一次请求后仍然存在)。

因此,当我们遇到Timeout异常时,上面的Fiddler2代码不起作用。没有Fiddler2,在相同的情况下使用相同的代码,一切正常。

我没有深入了解Fiddler2,但在我看来问题可能只是兼容VS2010和错误代码的内部代理(考虑到使用“更新”区域下的第2点(Fiddler2也在那里使用) )对于成功代码(即2xx - 3xx)工作正常)

感谢大家对此的关注。