Search code examples
c#genericsdotnet-httpclient

C# and Generics: how can I handle processing based on type?


I'm new to generics and I'm trying to make a generic HTTP GET method for my project (and possibly expand it to handle POST/PUT also). The following seems to work OK when the response is string based:

private async Task<T> HttpGetAsync<T>(Uri uri)
{
    var httpRequestMessage = new HttpRequestMessage()
    {
        Method = HttpMethod.Get,
        RequestUri = uri,
        Headers =
        {
            { "Authorization", $"Basic {encodedCredentials}"},
            { "Cache-Control", "no-cache" }
        }
    };

    var response = await _httpClient.SendAsync(httpRequestMessage);
    var content = await response.Content.ReadAsStringAsync();
    return JsonConvert.DeserializeObject<T>(content);
}

But in some cases, based on the type, I would like the response to be read using ReadAsByteArrayAsync() or ReadAsStreamAsync() instead of ReadAsStringAsync().

I think that I could probably do a getType() within the method, and read the response using the appropriate method, but I'm wondering if maybe there is a better way to do this?

Is this a bad idea/a bad usage of generics in general? Thanks for any information!


Solution

  • Use an interface:

    interface IContentReader<T>
    {
        T ReadAsync(HttpResponseMessage response);
    }
    
    private async Task<T> HttpGetAsync<T>(Uri uri, IContentReader<T> reader)
    {
        var httpRequestMessage = new HttpRequestMessage()
        {
            Method = HttpMethod.Get,
            RequestUri = uri,
            Headers =
            {
                { "Authorization", $"Basic {encodedCredentials}"},
                { "Cache-Control", "no-cache" }
            }
        };
    
        var response = await _httpClient.SendAsync(httpRequestMessage);
        return await reader.ReadAsync(response);
    }
    

    And you can have different implementations of IContentReader<T>. You can determine which implementation to use based on T.