title: How to capture an HttpClient request, without making the request
body: <p>I want to generate the contents of an Http request, but not actually make the request.  I just want to save it to disk.</p>
  <p>This is how I am doing it, and I'm not a big fan.  Currently just logging to the xUnit test logger for now.  Is there a better to log the request without actually executing it?  The biggest part I don't like is that my approach to capturing the request does the formatting, which may not actually be correct in all cases.</p>
  <pre><code>public async void GenerateWithHeader()
  {
      using (MultipartFormDataContent content = GenerateMultipartContent())
      {
          HttpClient c = new HttpClient(new RequestCaptureHandler(new HttpClientHandler(), this.output));
          HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Post, &quot;http://test.ca&quot;);
  
          //we want xml back
          msg.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(&quot;application/xml&quot;));
  
          msg.Content = content;
  
          try
          {
              await c.SendAsync(msg);
          }
          catch (InvalidOperationException)
          {
              //suppress it.  we don't actually want to make the request
          }
      }
  }
  
  public class RequestCaptureHandler : DelegatingHandler
  {
      private readonly ITestOutputHelper output;
      public RequestCaptureHandler(HttpMessageHandler innerHandler, ITestOutputHelper output)
          : base(innerHandler)
      {
          this.output = output;
      }
  
      protected override async System.Threading.Tasks.Task&lt;HttpResponseMessage&gt; SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
      {
          //The Request-Line begins with a method token, followed by the Request-URI and the protocol version, and ending with CRLF.The elements are separated by space characters.
          //Request-Line = Method &lt;space&gt; Request-URI &lt;space&gt; HTTP-Version CRLF
          this.output.WriteLine($&quot;{request.Method} {request.RequestUri.ToString()} {request.Version}&quot;);
  
          //Zero or more header (General|Request|Entity) fields followed by CRLF
          foreach (var h in request.Headers)
          {
              this.output.WriteLine($&quot;{h.Key}: {string.Join(' ', h.Value)}&quot;);
          }
                  
          foreach (var h in request.Content.Headers)
          {
              this.output.WriteLine($&quot;{h.Key}: {string.Join(' ', h.Value)}&quot;);
          }
  
          //An empty line (i.e., a line with nothing preceding the CRLF)  indicating the end of the header fields
          this.output.WriteLine(&quot;&quot;);
  
          //Optionally a message-body
          if (request.Content != null)
          {
              this.output.WriteLine(await request.Content.ReadAsStringAsync());
          }
  
          //Don't actually want to make the request.  This will cause an InvalidOperationException when the SendAsync function of HttpClient is called.
          return null;
      }
  }
  </code></pre>