C# 将数据发布到HTTPS url时,GetRequestStream()引发超时异常

C# 将数据发布到HTTPS url时,GetRequestStream()引发超时异常,c#,asp.net-mvc,post,https,httprequest,C#,Asp.net Mvc,Post,Https,Httprequest,我正在调用Apache服务器上托管的API来发布数据。我正在使用HttpWebRequest在C#中执行POST API在服务器上同时具有普通HTTP和安全层(HTTPS)端口。当我调用HTTP URL时,它工作得非常好。然而,当我调用HTTPS时,它会给我超时异常(在GetRequestStream()函数处)。有什么见解吗?我正在使用VS2010、.NETFramework 3.5和C。以下是代码块: string json_value = jsonSerializer.Serialize(

我正在调用Apache服务器上托管的API来发布数据。我正在使用HttpWebRequest在C#中执行POST

API在服务器上同时具有普通HTTP和安全层(HTTPS)端口。当我调用HTTP URL时,它工作得非常好。然而,当我调用HTTPS时,它会给我超时异常(在GetRequestStream()函数处)。有什么见解吗?我正在使用VS2010、.NETFramework 3.5和C。以下是代码块:

string json_value = jsonSerializer.Serialize(data);


        HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com");
        request.Method = "POST";
        request.ProtocolVersion = System.Net.HttpVersion.Version10;
        request.ContentType = "application/x-www-form-urlencoded";

        byte[] buffer = Encoding.ASCII.GetBytes(json_value);
        request.ContentLength = buffer.Length;
        System.IO.Stream reqStream = request.GetRequestStream();
        reqStream.Write(buffer, 0, buffer.Length);
        reqStream.Close();
编辑: Peter建议的控制台程序运行良好。但当我添加需要发布到API的数据(JSON格式)时,它抛出操作超时异常。下面是我添加到基于控制台的应用程序中的代码,它会抛出错误

byte[] buffer = Encoding.ASCII.GetBytes(json_value);
request.ContentLength = buffer.Length;

我不知道这是否会帮助你解决你的具体问题,但是当你完成这些任务时,你应该考虑处理其中的一些东西。我最近做了一些类似的事情,在using语句中封装了一些东西,似乎为我清除了一堆超时异常

            using (var reqStream = request.GetRequestStream())
            {
                if (reqStream == null)
                {
                    return;
                }

              //do whatever

            }
还要检查这些东西

  • 服务器是否在本地开发环境中提供https服务
  • 您是否正确设置了绑定*.443(https)
  • 您需要为请求设置凭据吗
  • 是您的应用程序池帐户访问https资源,还是您的帐户正在通过
  • 你想过改用WebClient吗

    using (WebClient client = new WebClient())
        {               
            using (Stream stream = client.OpenRead("https://server-url-xxxx.com"))
            using (StreamReader reader = new StreamReader(stream))
            {
                MessageBox.Show(reader.ReadToEnd());
            }
        }
    
编辑:

从控制台发出请求

internal class Program
{
    private static void Main(string[] args)
    {
        new Program().Run();
        Console.ReadLine();
    }

    public void Run()
    {

       var request = (HttpWebRequest)System.Net.WebRequest.Create("https://server-url-xxxx.com");
        request.Method = "POST";
        request.ProtocolVersion = System.Net.HttpVersion.Version10;
        request.ContentType = "application/x-www-form-urlencoded";

        using (var reqStream = request.GetRequestStream())
        {
            using(var response = new StreamReader(reqStream )
            {
              Console.WriteLine(response.ReadToEnd());
            }
        }
    }
}

您可能需要设置timeout属性,请在此处选中它

我遇到了相同的问题。看来这对我来说已经解决了。我检查了所有代码,确保为所有HttpWebResponse对象调用webResponse.Close()和/或responseStream.Close()。文档表明可以关闭流或HttpWebResponse对象。两个都打没有害处,所以我打了。如果不关闭响应,可能会导致应用程序失去可重用的连接,就我在代码中观察到的情况而言,这似乎会影响HttpWebRequest.GetRequestStream。

尝试以下操作:

    WebRequest req = WebRequest.Create("https://server-url-xxxx.com");
    req.Method = "POST";
    string json_value = jsonSerializer.Serialize(data); //Body data
    ServicePointManager.Expect100Continue = false;
    using (var streamWriter = new StreamWriter(req.GetRequestStream()))
    {
        streamWriter.Write(json_value);
        streamWriter.Flush();
        streamWriter.Close();
    }
    HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
    Stream GETResponseStream = resp.GetResponseStream();
    StreamReader sr = new StreamReader(GETResponseStream);
    var response = sr.ReadToEnd(); //Response
    resp.Close(); //Close response
    sr.Close(); //Close StreamReader
并查看URI:

  • 保留字符。发送URI可以带来的保留字符 问题
    !*'( ) ; : @ & = + $ , / ? # []

  • URI长度:不应超过2000个字符


    • 我也遇到了这个问题。我想用一个控制台应用程序模拟数百名用户。当只模拟一个用户时,一切正常。但随着用户的增加,超时异常一直在出现

      发生超时是因为默认情况下,到ServicePoint(又名网站)的ConnectionLimit=2。 非常好的文章阅读:

      您可以做的是:

      1) 在servicePoint中创建更多的ConnectionGroup,因为ConnectionLimit是每个ConnectionGroup

      2) 或者只是简单地增加连接限制

      请参阅我的解决方案:

      private HttpWebRequest CreateHttpWebRequest<U>(string userSessionID, string method, string fullUrl, U uploadData)
      {
          HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(fullUrl);
          req.Method = method; // GET PUT POST DELETE
          req.ConnectionGroupName = userSessionID;  // We make separate connection-groups for each user session. Within a group connections can be reused.
          req.ServicePoint.ConnectionLimit = 10;    // The default value of 2 within a ConnectionGroup caused me always a "Timeout exception" because a user's 1-3 concurrent WebRequests within a second.
          req.ServicePoint.MaxIdleTime = 5 * 1000;  // (5 sec) default was 100000 (100 sec).  Max idle time for a connection within a ConnectionGroup for reuse before closing
          Log("Statistics: The sum of connections of all connectiongroups within the ServicePoint: " + req.ServicePoint.CurrentConnections; // just for statistics
      
          if (uploadData != null)
          {
              req.ContentType = "application/json";
              SerializeToJson(uploadData, req.GetRequestStream());
          }
          return req;
      }
      
      /// <summary>Serializes and writes obj to the requestStream and closes the stream. Uses JSON serialization from System.Runtime.Serialization.</summary>        
      public void SerializeToJson(object obj, Stream requestStream)
      {
          DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType());
          json.WriteObject(requestStream, obj);            
          requestStream.Close();
      }
      
      private HttpWebRequest CreateHttpWebRequest(字符串userSessionID、字符串方法、字符串fullUrl、U uploadData)
      {
      HttpWebRequest req=(HttpWebRequest)HttpWebRequest.Create(fullUrl);
      req.Method=Method;//GET PUT POST DELETE
      req.ConnectionGroupName=userSessionID;//我们为每个用户会话创建单独的连接组。在一个组中,可以重用连接。
      req.ServicePoint.ConnectionLimit=10;//ConnectionGroup中的默认值2始终导致我出现“超时异常”,因为用户在一秒钟内并发了1-3个WebRequests。
      req.ServicePoint.MaxIdleTime=5*1000;//(5秒)默认值为100000(100秒)。关闭前,ConnectionGroup内的连接可重用的最大空闲时间
      Log(“统计信息:ServicePoint内所有ConnectionGroup的连接总数:”+req.ServicePoint.CurrentConnections;//仅用于统计信息
      if(上传数据!=null)
      {
      req.ContentType=“应用程序/json”;
      SerializeToJson(上传数据,req.GetRequestStream());
      }
      返回请求;
      }
      ///序列化obj并将其写入requestStream并关闭该流。使用System.Runtime.serialization中的JSON序列化。
      public void序列化为JSON(对象obj,Stream requestStream)
      {
      DataContractJsonSerializer json=新的DataContractJsonSerializer(obj.GetType());
      WriteObject(requestStream,obj);
      requestStream.Close();
      }
      
      感谢您的回复。1.不,它不提供服务2.是的3.不。4.您能详细说明一下吗?我没有理解。5.我尝试了WebClient,但在.OpenRead中,它抛出了操作超时错误。再更新一次-我已经设置了简单的Python应用程序,通过HTTPS访问相同的API,它的工作非常好。所以看起来只有.Net有问题。不知道为什么。你在运行cassini、iisexpress或iis吗?你能在控制台应用程序中试用吗。我正在cassini上的本地开发环境中运行此应用程序。很抱歉,这听起来可能不方便,但你如何在控制台应用程序中试用它?谢谢你的回答。我已经设置了,但仍然无法工作。你能在没有ProtocolVersion和C的情况下试用吗ontentTypes还可以获取wireshark,并查看网络中发生的情况。检查目标服务器是否接受跨域调用。谢谢Peter。我添加了ProtocolVersion和ContentType,但似乎没有多大帮助。我将与wireshark进行检查,但由于Python应用程序可以轻松获取/发布到API,我相信服务器正在接受跨域calls.it’当我为Azure移动服务使用REST API时,事实上,这与@Peter
      StreamWriter
      在其
      Dispose()中调用
      Flush()
      &
      Close()
      的公认答案相同
      方法,将为您的使用块调用该方法。非常感谢您关闭Response and StreamReader,它为我工作了。