-1

I'm wondering if my implementation in my webAPI is correct:

Startup.cs => ConfigureServices

services.AddHttpClient("MyHttpClient")

Startup.cs => Configure

applicationLifetime.ApplicationStopping.Register(() => {
   MyController.httpClient.Dispose();
});

Controller

private static IHttpClientFactory _httpClientFactory;
public static HttpClient httpClient = null;

public MyController(IHttpClientFactory httpClientFactory)
{
     _httpClientFactory = httpClientFactory;

     if (httpClient == null)
     {
         httpClient = _httpClientFactory.CreateClient("MyHttpClient");
     }
}

Methods

[HttpGet]
[Consumes("application/x-www-form-urlencoded")]
public async void MyMethod1() {
   await httpClient.SendAsync() 
   ....
}


[HttpGet]
[Consumes("application/x-www-form-urlencoded")]
public async void MyMethod2() {
   await httpClient.SendAsync() 
   ....
}
3
  • 1
    Can't really see a major problem in your implementation. I would just suggest that you use Task rather than void in the API controller actions Commented Sep 10, 2023 at 10:04
  • Does code run if it is not run as a services? Usually code fails as a service unless you start the service as a Service Account. A service defaults to a System Account which doesn't have an Environment and often will fail. Do you see the service running in Task Manager? If you do not see it running it probably terminated. Check Event Viewer to see if there are any error indicating failure. Commented Sep 10, 2023 at 10:07
  • Have you tested it? Commented Jan 24, 2024 at 15:11

1 Answer 1

0

I'm wondering if my implementation in my webAPI is correct

Well, based on your shared code snippet apparently seems that implementations would work. However, you can improve it in few areas. For instance, you have made IHttpClientFactory as private static but the recommended practice is, it should be private readonly, I'm not sure, why have you decorate with static, do you want the value of this variable would be changed only in the static constructor or not.

Another important point is that, async call should be deal with Task and async Task is the natural approach because, if you use async void which has critical disadvantages and can restricted to your event handler also block your request pool. This is why async void is never encourage to use. You can get more details here.

Finally, I found one more inconsistency but its minor, however, I am little scrupulous here in this line, if you define HttpClient httpClient = null that means, you want this as nullable, so this should be as following:

public readonly HttpClient? httpClient = null;

So I left HttpClient? as nullable, thus the null assignment wouldn't yell at me.

Therefore, I think, your whole implementation can be improved as following:

public class MyController : Controller
    {

        private readonly IHttpClientFactory _httpClientFactory;
        public readonly HttpClient? httpClient = null;

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

        [HttpGet]
        [Consumes("application/x-www-form-urlencoded")]
        public async Task MyMethod1()
        {
            await httpClient.SendAsync();
        }
        
    }

Apart from above implementation, I would like to inform, depending on the requirement there are several ways for IHttpClientFactory you could consier.

For example, CreateClient and Typedclients of IHttpClientFactory

Note: Please refer to this official document, if you want to know more details about other consumption pattern.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.