title: Converting the content of HttpResponseMessage to object
body: <p><em>My Question: <strong>How do I do this?</em></strong></p>
  
  <p>So, I hadn't touched anything .Net in about 6 years until this week. There's a lot that I've forgotten and even more that I never knew and while I love the idea of the async/await keywords, I'm having a slight problem implementing the following requirements for a client's API implementation:</p>
  
  <ol>
  <li>The <code>ServerAPI</code> class has a method for each of the API methods, taking appropriate input parameters (e.g. the method <code>Login</code> takes in an <code>id</code> and a <code>password</code>, makes the API call and returns the result to the caller).</li>
  <li>I want to abstract away the JSON so that my API methods return the actual object you're fetching (e.g. the <code>Login</code> method above returns a <code>User</code> object with your auth token, uid, etc.)</li>
  <li>Some API methods return a 204 on success or no meaningful content (not meaningful in my usecase maybe I only care about success/failure), for these I'd like to return either a bool (<code>true</code> = success) or the status code.</li>
  <li>I'd like to keep the async/await (or equivalent) design, because it seems to really work well so far.</li>
  <li>For some methods, I might need to just return the <code>HttpResponseMessage</code> object and let the caller deal with it.</li>
  </ol>
  
  <p>This is roughly what I have so far and I'm not sure how to make it compliant with the above OR whether I'm even doing this right. Any guidance is appreciated (flaming, however, is not).</p>
  
  <pre><code>// 200 (+User JSON) = success, otherwise APIError JSON
  internal async Task&lt;User&gt; Login (string id, string password)
  {
      LoginPayload payload = new LoginPayload() { LoginId = id, Password = password};
      var request = NewRequest(HttpMethod.Post, "login");
      JsonPayload&lt;LoginPayload&gt;(payload, ref request);
  
      return await Execute&lt;Account&gt;(request, false);
  }
  
  // 204: success, anything else failure
  internal async Task&lt;Boolean&gt; LogOut ()
  {
      return await Execute&lt;Boolean&gt;(NewRequest(HttpMethod.Delete, "login"), true);
  }
  
  internal async Task&lt;HttpResponseMessage&gt; GetRawResponse ()
  {
      return await Execute&lt;HttpResponseMessage&gt;(NewRequest(HttpMethod.Get, "raw/something"), true);
  }
  
  internal async Task&lt;Int32&gt; GetMeStatusCode ()
  {
      return await Execute&lt;Int32&gt;(NewRequest(HttpMethod.Get, "some/intstatus"), true);
  }
  
  private async Task&lt;RESULT&gt; Execute&lt;RESULT&gt;(HttpRequestMessage request, bool authenticate)
  {
      if (authenticate)
          AuthenticateRequest(ref request); // add auth token to request
  
      var tcs = new TaskCompletionSource&lt;RESULT&gt;();
      var response = await client.SendAsync(request);     
  
      // TODO: If the RESULT is just HTTPResponseMessage, the rest is unnecessary        
  
      if (response.IsSuccessStatusCode)
      {
          try
          {
              // TryParse needs to handle Boolean differently than other types
              RESULT result = await TryParse&lt;RESULT&gt;(response);
              tcs.SetResult(result);
          }
          catch (Exception e)
          {
              tcs.SetException(e);
          }
  
      }
      else
      {
          try
          {
              APIError error = await TryParse&lt;APIError&gt;(response);
              tcs.SetException(new APIException(error));
          }
          catch (Exception e)
          {
              tcs.SetException(new APIException("Unknown error"));
          }
      }
  
      return tcs.Task.Result;
  }
  </code></pre>
  
  <p>This is the <code>APIError</code> JSON structure (it's the status code + a custom error code). </p>
  
  <pre><code>{
    "status": 404,
    "code":216,
    "msg":"User not found"
  }
  </code></pre>
  
  <p>I would prefer to stay with <code>System.Net</code>, but that's mostly because I don't want to switch all my code over. If what I want is easier done in other ways then it's obviously worth the extra work.</p>
  
  <p>Thanks.</p>