title: Why does HttpWebRequest.GetResponse() fail in an ASP.NET page under IIS?
body: <p>I built a set of API's for one of our developers to consume in our web application. I did this in a .NET 4.0 class library project and wrote integration tests to ensure the API integrated with the backend service correctly. In the integration tests (a unit test project), as well as a console application, the API's work correctly and return all the expected results. However, when we execute the same API's from a ASP.NET web page that is running under IIS, the API fails at the following line of code:</p>
  
  <pre><code>using (HttpWebResponse response = (HttpWebRequest)request.GetResponse())
  </code></pre>
  
  <p>The failure is a <code>WebException</code> with a status of <code>SendFailure</code> and a socket error of <code>ConnectionReset  (10054)</code> in the inner exception. The error is <code>The underlying connection was closed: An unexpected error occurred on a send</code>. This is using HTTPS, as well (hence the X509).</p>
  
  <p>I already know that this is actually when the request is made, but I'm trying to pin-point what is different about an IIS environment that would prevent the stream from being able to write bytes over the network. I know that this is actually the web service server closing the connection before we get a chance to send our data, but I want to urge, again, that this same API works fine under a integration or unit test, or console application all day long.</p>
  
  <p>I have already exhausted as many articles and posts on the internet that are related that I could find, including extensive Msdn documentation such as checking things related to the certificate, modifying HTTP headers service point properties. I'm truly at a loss because the code is not complicated, I've written web request code too many times to count, but here it is:</p>
  
  <pre><code>private string ExecuteServiceMessages(Uri serviceUrl, X509Certificate clientCertificate, string requestBody)
  {
      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUrl);
  
      request.ClientCertificates.Add(clientCertificate);
      request.Date = DateTime.Now;
      request.Method = WebRequestMethods.Http.Post;
      request.ContentType = MediaTypeNames.Text.Xml;
      request.UserAgent = "******";
      request.KeepAlive = false;
  
      using (Stream requestStream = request.GetRequestStream())
      using (StreamWriter writer = new StreamWriter(requestStream))
      {
          writer.Write(requestBody);
          writer.Close();
      }
  
      using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
      using (Stream responseStream = response.GetResponseStream())
      using (StreamReader reader = new StreamReader(responseStream))
      {
          string data = reader.ReadToEnd();
  
          reader.Close();
  
          return data;
      }
  }
  </code></pre>
  
  <p>The certificate is being loaded in by <code>X509Certificate.CreateFromCertFile</code>, where our certificate for testing is just in a directory of the website. We're not pulling it directly from the certificate store (unless we don't fully understand how certificates work when loaded from a file).</p>