Home > Back-end >  Issues setting up IHttpClientFactory in .NET Core 3.1
Issues setting up IHttpClientFactory in .NET Core 3.1

Time:10-13

I'm trying to set up an instance on IHttpClientFactory within .NET Core 3.1.

I have a route which is intended to make an GET request to an endpoint supplied by the user and return the result as a byte[].

In the first sample shown below I am getting an error in Visual Studio stating, "IHttpClientFactory is a type which is not valid in the current context".

But this is the type I am specifying in my constructor for DemoProcessor()

https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0119?f1url=?appId=roslyn&k=k(CS0119)

What am I doing wrong below and how should I be calling, or what argument should I be passing to DemoProcessor() in order for this to run correctly?

namespace POC_APP.Controllers
{
    [ApiController]
    [Route("api/")]
    public class DemoController : ControllerBase
    {
        [HttpGet("Interact", Name ="Interact")] 
        public async Task<ActionResult<string>> GetStringFromEndpointAsync(string url)
        {
            var proc = new DemoProcessor(IHttpClientFactory); // HERE
            var res = await proc.MakeGetRequest(url);
            return res.ToString();
        }
    }
}

As seen above I am trying to call my DemoProcessor() class which contains the implementation of IHttpClientFactory as below.

namespace POC_APP
{
    public class DemoProcessor 
    {

        private readonly IHttpClientFactory _httpClientFactory;

        public DemoProcessor(IHttpClientFactory httpClientFactory) =>
            _httpClientFactory = httpClientFactory;

        public async Task<byte[]> MakeGetRequest(string url)
        {
            byte[] response = null;
            try
            {
                using (var httpClient = _httpClientFactory.CreateClient())
                {
                    httpClient.DefaultRequestHeaders.Accept.Clear();
                    httpClient.DefaultRequestHeaders.Add("foo", "bar");

                    var documentResponse = await httpClient.GetStringAsync(url.Replace(".exe", ""));

                    response = Convert.FromBase64String(documentResponse);
                    return response;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                return response;
            }
        }
    }
}

I am adding the HTTP client like so in Startup.cs which is called by Program.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddHttpClient();
    }

CodePudding user response:

DemoProcessor has been setup to expect an instance of something which implements IHttpClientFactory, what is being passed is just the name 'IHttpClientFactory'. This wouldn't compile in any scenario. If you wanted to give the type even then you would need to do something like typeof(IHttpClientFactory).

As dependency injection comes out-of-the-box, you just need to inject IHttpClientFactory into your DemoController, and then pass it on.

namespace POC_APP.Controllers
{
    [ApiController]
    [Route("api/")]
    public class DemoController : ControllerBase
    {

        private readonly IHttpClientFactory _httpClientFactory;

        public DemoController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        [HttpGet("Interact", Name ="Interact")] 
        public async Task<ActionResult<string>> GetStringFromEndpointAsync(string url)
        {
            var proc = new DemoProcessor(_httpClientFactory);
            var res = await proc.MakeGetRequest(url);
            return res.ToString();
        }
    }
}

Or, better still, you could register your DemoProcessor in the DI service and inject that into the controller, which will automatically get the IHttpClientFactory injected into it.

  • Related