Reputation: 505
I'm trying to configure multiple API urls in the Program.cs class in Blazor WASM. I'm not seeing an AddHttpClient extension like in server-side. Was wondering if anyone had an alternate solution for this?
Here's what I have so far:
var firstURI = new Uri("https://localhost:44340/");
var secondURI = new Uri("https://localhost:5001/");
void RegisterTypedClient<TClient, TImplementation>(Uri apiBaseUrl)
where TClient : class where TImplementation : class, TClient
{
builder.Services.AddHttpClient<TClient, TImplementation>(client =>
{
client.BaseAddress = apiBaseUrl;
});
}
// HTTP services
RegisterTypedClient<IFirstService, FirstService>(firstURI);
RegisterTypedClient<ISecondService, SecondService>(secondURI);
Upvotes: 16
Views: 16549
Reputation: 3
This might be heaps late. But I wanted to add that if you have many clients you want to register, you can always create a client factory extension and then add in the clients reading from appsettings.json into your programs.cs
public static class ClientFactoryExtension{
public static void AddClientAbstractFactory<THandler>(
this IServiceCollection services,
string clientName,
string url)
where THandler : AuthorizationMessageHandler
{
// register handler
services.AddTransient<THandler>();
// register client
services.AddHttpClient(clientName, client => client.BaseAddress = new Uri(url))
.AddHttpMessageHandler<THandler>();
}
}
Then you can create a method that lets you register all your clients like so:
public static class ClientServices{
public static IServiceCollection AddClientServices(this IServiceCollection Services, IConfiguration Configuration)
{
Services.AddClientAbstractFactory<Client1AuthorizationMessageHandler>(
"client1", Configuration.GetValue<string>("client1:BaseUrl"));
Services.AddClientAbstractFactory<Client2AuthorizationMessageHandler>(
"client2", Configuration.GetValue<string>("client2:BaseUrl"));
Services.AddClientAbstractFactory<Client3AuthorizationMessageHandler>(
"client3", Configuration.GetValue<string>("client3:BaseUrl"));
return Services;
}
}
And finally in programs.cs, you can do the following:
builder.Services.AddClientServices(builder.Configuration);
And done.
Upvotes: 0
Reputation: 93601
The current answer seems overly complicated.
You can simply use named HttpClients and inject the IHttpClientFactory
into a page instead and create a HttpClient for a specific named configuration.
e.g. This example provides both an authorised client and an anonymous one (to access anonymous server endpoints).
builder.Services.AddHttpClient("BlazorApp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddHttpClient("Anonymous", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));
@inject IHttpClientFactory clientFactory;
and use with
var httpClient = clientFactory.CreateClient("Anonymous");
var someData = await httpClient.GetFromJsonAsync<SomeData>($"api/someendpoint");
Upvotes: 4
Reputation: 676
This can be done with Blazor Client Side. First, in your client-side package, get the following nuget package: Microsoft.Extensions.Http
Then, create two classes for this example (normally you would use an interface, but a class on its own should work here. I am going to demonstrate two different base addresses being used so you know there is a difference.
public class GoogleService
{
private readonly HttpClient httpClient;
public GoogleService(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public string GetBaseUrl()
{
return httpClient.BaseAddress.ToString();
}
}
And the Yahoo Service:
public class YahooService
{
private readonly HttpClient httpClient;
public YahooService(HttpClient httpClient)
{
this.httpClient = httpClient;
}
public string GetBaseUrl()
{
return httpClient.BaseAddress.ToString();
}
}
Next, in your Client Program's Program.cs, you can do something like the following:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddHttpClient<GoogleService>(client =>
{
client.BaseAddress = new Uri("https://google.com/");
});
builder.Services.AddHttpClient<YahooService>(client =>
{
client.BaseAddress = new Uri("https://yahoo.com/");
});
await builder.Build().RunAsync();
}
Next, you can inject them into your front end like so, and see that they are indeed two different injected clients:
@page "/"
@inject BlazorHttpClientTest.Client.Clients.GoogleService googleService;
@inject BlazorHttpClientTest.Client.Clients.YahooService yahooService;
<h1>Hello, world!</h1>
<label>Google Address:</label><label>@googleAddress</label>
<label>Yahoo Address:</label><label>@yahooAddress</label>
@code{
string googleAddress;
string yahooAddress;
protected override void OnInitialized()
{
base.OnInitialized();
googleAddress = googleService.GetBaseUrl();
yahooAddress = yahooService.GetBaseUrl();
}
}
And just like that, you should have it working:
Let me know if you need me to explain anything else more in depth, otherwise, mark as answered if it works for you.
Upvotes: 36