I'm trying to get a named HttpClient
to work in an F# Web API project. When I make the call to CreateClient
on the injected IHttpClientFactory
instance and supply the name, I'm expecting the HttpClient
instance that I get back to include the settings I used when I add it to the services collection. However, the client I get back is a default.
Here is how I'm registering the named client.
// From: Program.fs
module Program =
let exitCode = 0
[<EntryPoint>]
let main args =
let builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllers()
builder.Services.AddHttpClient("MyClient", (fun client ->
let creds = Convert.ToBase64String(Encoding.ASCII.GetBytes($"user01:password123"))
client.BaseAddress <- Uri("https://my-service-url")
client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue("application/json"))
client.DefaultRequestHeaders.Authorization <- AuthenticationHeaderValue("Basic", creds)
)) |> ignore
...
Here is where I inject the factory into the controller and try to get an instance of the pre-configured named client.
// From: WeatherForecastController.fs
[<ApiController>]
[<Route("[controller]")>]
type WeatherForecastController (logger : ILogger<WeatherForecastController>, httpClientFactory:IHttpClientFactory) =
inherit ControllerBase()
let httpClient = httpClientFactory.CreateClient("MyClient")
...
When I inspect the httpClient
instance, I find that BaseAddress
is null. I'm expecting it to be https://my-service-url
since that was what I set in the call to AddHttpClient
.
I've tried to follow the docs but I may have missed something critical in the translation from C# to F#. If I set up this same exact sample in a C# app it works as expected.
Is there a mistake in the way I'm setting up the named client?
CodePudding user response:
You are trying to set the BaseAddress
property of the HttpClient
instance by using the <-
operator.
In F# the <-
operator is used for assigning values to variables, not for setting properties.
Use the BaseAddress
property setter like this::
client.BaseAddress <- new Uri("https://my-service-url")
Alternative:
client <- client with { BaseAddress = new Uri("https://my-service-url") }
CodePudding user response:
I found that the F# version works if I add a type parameter in the call to AddHttpClient
. So I changed the line
builder.Services.AddHttpClient("MyClient", (fun client ->
to
builder.Services.AddHttpClient<HttpClient>("MyClient", (fun client ->
and then it started working and giving back a configured HttpClient
instance as expected.