Converting the content of HttpResponseMessage to object
<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>