0

I am using the following code snipped as part of rest client. The code works as expected. Now, I want to extend to code to return the HttpRespnseMessage along with the result. The context is in case of an error calling function will evaluate the Response message for status code and errors if any. How to return the status code along with result like <TResult, HttpResponseMessage>.

public async Task<TResult> MakeApiCall<TResult>(string url, HttpMethod method, bool auth, string data = null) where TResult : class
{
    using (var httpClient = new HttpClient())
    {
        httpClient.Timeout = new TimeSpan(0, 0, 10);

        using (var request = new HttpRequestMessage { RequestUri = new Uri(url), Method = method })
        {
            request.Headers.Accept.Clear();
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // add content
            if (method != HttpMethod.Get)
            {
                request.Content = new StringContent(data, Encoding.UTF8, "application/json");
            }

            if (auth)
            {
                request.Headers.Add("X-Service-Token", _authUser.ServiceApiKey);
            }

            HttpResponseMessage response = new HttpResponseMessage();
            try
            {
                response = await httpClient.SendAsync(request).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                if (response != null)
                {
                    Debug.WriteLine(response.StatusCode.ToString());
                }
                return null;
            }

            var stringSerialized = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
            // Debug.WriteLine(stringSerialized);

            // deserialize content
            try
            {
                var desrialized_data = JsonConvert.DeserializeObject<TResult>(stringSerialized, Converter.Settings);
                return desrialized_data;
            }
            catch (JsonReaderException ex)
            {
                Debug.WriteLine("JsonReaderException");
                Debug.WriteLine(ex.ToString());
                return null;
            }
            catch (JsonSerializationException ex)
            {
                Debug.WriteLine("JsonSerializationException");
                Debug.WriteLine(ex.ToString());
                return null;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return null;
            }
        }
    }
}

Edit2: As Alexei Levenkov pointed out my question seems to be almost duplicate. I am still accepting the Michael's answer as it shows how to return multiple values in the context of Async Task

gv1507
  • 47
  • 4
  • 10
  • `HttpResponseMessage` is `IDisposable`. You really don't want to have that float around after the method is called. It should be disposed of asap. What are you trying to achieve by returning it? – Enigmativity Feb 05 '19 at 01:47
  • https://stackoverflow.com/questions/52078784/chain-of-responsibility-in-exceptionmiddleware-net-core/52079914#52079914 – PmanAce Feb 05 '19 at 01:48
  • @Enigmativity, I am trying to return the status code and error message(s) if any – gv1507 Feb 05 '19 at 01:54
  • @gv1507 - Then return those and not `HttpResponseMessage`. Michael's answer and the linked duplicate answer then apply. Just don't return anything that implements `IDisposable` unless you understand that it isn't already disposed and that you must explicitly do so - it other words you are taking explicit control of the lifetime of the disposable. – Enigmativity Feb 05 '19 at 02:00
  • @gv1507 - "I was looking for an answer in the context of HttpResponse." - Why? What's the difference that you see? – Enigmativity Feb 05 '19 at 02:00
  • @Enigmativity, IDisposable was an eye opener. As suggested I would avoid returning IDisposable as far as possible or dispose it explicitly. – gv1507 Feb 05 '19 at 02:07
  • @Enigmativity, Sorry for confusion. English is not my first language. I did not mean to imply that there is difference. I have removed my first edit. – gv1507 Feb 05 '19 at 02:22

1 Answers1

3

Just use a Tuple with the types you need

public async Task<(TResult,string)> MakeApiCall<TResult>(...)
{

    ...
    return (response,somethingElse);

    // or

    return null;

C# tuple types

Update

As Enigmativity has rightly said

HttpResponseMessage is IDisposable so it shouldn't be returned outside of the method.

TheGeneral
  • 79,002
  • 9
  • 103
  • 141