I have an ASP.NET Core Web API project as the backend and a Blazor web assembly as the front-end.
The Web API has ProductController which returns JSON data (products, groups, etc). Blazor app consumes that API.
I created ProductService on the Blazor side. The ProductService gets HttpClient in constructor injection and sends requests to the API. And here is the problem — I get a 404 NotFound error. When I use injected HttpClient or create it directly on the page it works (please see the code shown below).
If I input API URL in a browser I get the data (product catalog).I initialize HttpClient as Microsoft says in the article.Please help to fix this.
This is the Blazor init code:
var builder = WebAssemblyHostBuilder.CreateDefault(args);builder.RootComponents.Add<App>("#app");builder.RootComponents.Add<HeadOutlet>("head::after");builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);var appSettings = builder.Configuration.Get<AppSettings>();builder.Services.AddSingleton<AppSettings>(appSettings);builder.Services.AddBlazoredLocalStorage();builder.Services.AddHttpClient("Shop.WebApi", client => client.BaseAddress = new Uri(appSettings.ApiBaseUri)) .AddHttpMessageHandler<CustomAuthorizationMessageHandler>();builder.Services.AddScoped<CustomAuthorizationMessageHandler>();builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("Shop.WebApi"));builder.Services.AddApiAuthorization();builder.Services.AddScoped<CustomAuthenticationStateProvider>();builder.Services.AddScoped<AuthenticationStateProvider>( provider => provider.GetRequiredService<CustomAuthenticationStateProvider>());builder.Services.AddScoped<AuthService>();builder.Services.AddHttpClient<IProductService, HttpProductService>(client =>{ client.BaseAddress = new Uri(appSettings.ApiBaseUri);}).AddHttpMessageHandler<CustomAuthorizationMessageHandler>();await builder.Build().RunAsync();This is product catalog page:
@inject IProductService ProductService@inject HttpClient TheHttpClient...protected override async Task OnInitializedAsync(){ try { // this works _ProductCatalog = await TheHttpClient.GetFromJsonAsync<ProductCatalog>("api/Product/GetProductCatalog"); // this doesn't work //await LoadProductCatalogAsync(); } catch (Exception ex) { Console.WriteLine("An error occurred while initializing the page: " + ex.Message); }}private async Task LoadProductCatalogAsync(){ try { _ProductCatalog = await ProductService.GetProductCatalog(); } catch (Exception ex) { Console.WriteLine("An error occurred while loading the product catalog: " + ex.Message); }}Product service:
public class HttpProductService : IProductService{ public HttpProductService(HttpClient httpClient) { TheHttpClient = httpClient; } public async Task<ProductCatalog> GetProductCatalog() { var response = await TheHttpClient.GetAsync($"{GetApiBaseUri()}"); if (response.IsSuccessStatusCode) { return await response.Content.ReadFromJsonAsync<ProductCatalog>(); } return new ProductCatalog(); } protected virtual string GetApiBaseUri() => $"api/Product"; protected HttpClient TheHttpClient { get; }}