Search code examples
c#async-awaithttpresponsemessage

How do I get read through httpresponse to get return values:


I think I am close to getting this to work but am not sure how to get the contents to find out what the result message is returned in content to see if it is a good record or not, and I just don't know how. I've gotten close...can see my values in Visual Studio Locals but can't get to them.

These are my data classes:

public class PurchaseOrder
{
    private List<POHeader> _headers = new List<POHeader>();
    private List<PODetail> _details = new List<PODetail>();

    [JsonProperty("HeaderAttributes")]
    public List<POHeader> Header
    {
        get { return _headers; }
        set { _headers = value; }
    }

    [JsonProperty("LineAttributes")]
    public List<PODetail> Details
    {
        get { return _details; }
        set { _details = value; }
    }    
}

public class POHeader
{
    private string _poNumber;
    private int _resultCode;
    private string _resultMessage;

    [JsonProperty("po_number")]
    public string PONumber
    {
        get { return _poNumber; }
        set { _poNumber = value; }
    }

    [JsonProperty("result_code")]
    public int ResultCode
    {
        get { return _resultCode; }
        set { _resultCode = value; }
    }

    [JsonProperty("result_msg")]
    public string ResultMsg
    {
        get { return _resultMessage; }
        set { _resultMessage = value; }
    }    
}

This is in APIClient class:

public async Task<HttpResponseMessage> PostStreamAsync(string requestUrl, CancellationToken cancellationToken, object content)
{
    addHeaders();

    using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
    using (var httpContent = CreateHttpContentForStream(content))
    {
        request.Content = httpContent;

        using (var response = await _httpClient
            .SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken)
            .ConfigureAwait(false))
        {
            response.EnsureSuccessStatusCode();
            return response;
        }
    }
}

This is my task in TransmitPO class:

public static async Task TransmitToService(List<PurchaseOrder> orders, CancellationToken cancellationToken, string path)
{
    ApiClient _client = new ApiClient(new Uri("myUrl"), "code");

    var results = await _client.PostStreamAsync(path, cancellationToken, orders);
    var deserializedResults = JsonConvert.DeserializeObject<List<PurchaseOrder>>(results);
}

And this is how I call it when it is running through process code:

await TransmitToService(poList, CancellationToken.None, poPath);

This is where I create my HttpClient...good, bad, worse? public partial class ApiClient { private readonly HttpClient _httpClient; private Uri BaseEndpoint { get; set; }

    private string AuthToken { get; set; }

    public ApiClient(Uri baseEndpoint, string bToken)
    {
        BaseEndpoint = baseEndpoint;
        AuthToken = bToken;
        _httpClient = new HttpClient();
    }
}

Solution

  • You're trying to deserialize (the disposed) HttpResponseMessage, not its content.

    private static readonly HttpClient _httpClient = new HttpClient();
    
    public async Task<T> PostStreamAsync<T>(string requestUrl, CancellationToken cancellationToken, object content)
    {
        addHeaders();
    
        using (var request = new HttpRequestMessage(HttpMethod.Post, requestUrl))
        using (var httpContent = CreateHttpContentForStream(content))
        {
            request.Content = httpContent;
    
            using (var response = await _httpClient
                .SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken)
                .ConfigureAwait(false))
            {
                response.EnsureSuccessStatusCode();
                return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
            }
        }
    }
    
    var deserializedResults = _client.PostStreamAsync<List<PurchaseOrder>>(path, cancellationToken, orders);
    

    Also you should ensure that you're not creating new HttpClient per request, otherwise you'll get unstable ApiClient implementation.