我有一个 ASP.NET Core Web API 项目作为后端,有一个 Blazor Web 程序集作为前端。
Web API 具有
ProductController
,它返回 JSON 数据(产品、组等)。 Blazor 应用程序使用该 API。
我在 Blazor 端创建了
ProductService
。 ProductService
在构造函数注入中获取 HttpClient
并向 API 发送请求。问题是——我收到 404 NotFound 错误。当我使用注入的 HttpClient
或直接在页面上创建它时,它可以工作(请参阅下面显示的代码)。
如果我在浏览器中输入 API URL,我会获取数据(产品目录)。 我按照微软在文章中所说的
初始化
HttpClient
。
请帮忙解决这个问题。
这是 Blazor 初始化代码:
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();
这是产品目录页面:
@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);
}
}
产品服务:
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; }
}
GetProductCatalog
中的URL是“api/Product”而不是“api/Product/GetProductCatalog”。在
GetApiBaseUri()
后添加“/GetProductCatalog”路径。
public class HttpProductService : IProductService
{
...
public async Task<ProductCatalog> GetProductCatalog()
{
var response = await TheHttpClient.GetAsync($"{GetApiBaseUri()}/GetProductCatalog");
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadFromJsonAsync<ProductCatalog>();
}
return new ProductCatalog();
}
...
}