简体   繁体   English

重试POST请求会丢失正文C#WinForms

[英]Retrying POST request loses body c# winforms

I faced with the issue that after retrying the request my POST data got lost somehow. 我遇到的问题是,重试请求后,我的POST数据以某种方式丢失了。 Code sample below. 下面的代码示例。 ( Please note that request.timeout = 1 set for testing purposes to reproduce the behavior shown in the code below ): 请注意,出于测试目的,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
            }
        }
    }

The magic is that first request (until Request timeout error) goes well. 魔术是第一个请求(直到请求超时错误)进展顺利。 Further requests are going without POST data, but content length is counted properly (ie stays the same as in previous request). 没有 POST数据的其他请求将继续进行 ,但是内容长度已正确计数(即与先前请求中的相同)。


Updated: 更新:

  1. post_data_final getting is separate function. post_data_final获取是单独的功能。 It is not used (except byteArray) or changed in request_3() function. 它不被使用(byteArray除外)或在request_3()函数中进行了更改。
  2. Request works fine if it got into for loop and Timeout exception has not occured . 如果请求进入for循环并且没有发生超时异常,则请求工作正常。 So if I just put my request into for loop it will do particular number of valid requests. 因此,如果我只是将请求放入for循环中,它将执行特定数量的有效请求。 As soon as I'm getting Timeout exception, the next request will be without POST data. 一旦我收到超时异常,下一个请求将不包含POST数据。
  3. Source code is edited for those who thinks that recursion is a bad idea. 对于认为递归不是一个好主意的人,对源代码进行了编辑。 The edited code still doesn't work. 编辑后的代码仍然无法使用。

Any suggestions are appreciated 任何建议表示赞赏

I cant find anything wrong in your code, so provide mode details, as the comments mentioned. 我在您的代码中找不到任何错误,请提供模式详细信息,如注释中所述。

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;
         }
    }
}

The issue was because of using Fiddler2 - analogue of Wireshark (ie intercepting traffic tool). 问题是由于使用了Fiddler2-Wireshark的类似物(即拦截交通工具)。

Requested site uses https protocol. 请求的网站使用https协议。 For debugging purposes I installed Fiddler2 and Fiddler2 certificate to be able to see all incoming and outcoming responses. 为了进行调试,我安装了Fiddler2和Fiddler2证书,以便能够查看所有传入和传出的响应。 For some magic reason when I turned off Fiddler2 and added some additional logging into console, i figured out that requests are appeared to be valid (ie POST body data still exists after first request). 出于某种神奇的原因,当我关闭Fiddler2并向控制台添加一些其他日志记录时,我发现请求似乎是有效的(即,在第一个请求之后POST正文数据仍然存在)。

So with Fiddler2 code above doesn't work while we're having Timeout exception. 因此,当我们遇到Timeout异常时,上面的Fiddler2代码不起作用。 Without Fiddler2 everything works fine under the same circumstances and using the same code. 没有Fiddler2,在相同的环境下使用相同的代码,一切都可以正常工作。

I didn't dig deep into Fiddler2, but seems to me issue could be only with compatibility of VS2010 and internal proxy for Error Codes (taking into account that using point 2 under "Updates" area (The Fiddler2 was also used there) for success codes (ie 2xx - 3xx) worked fine) 我没有深入研究Fiddler2,但是在我看来,问题可能仅在于VS2010和错误代码的内部代理的兼容性(考虑到使用“更新”区域下的第2点(那里也使用了Fiddler2))代码(即2xx-3xx)工作正常)

Thanks everyone for getting attention into this. 感谢大家对此的关注。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM