Reputation: 653
Following on from this question: Blazor Server Initiating Task Halts Application I am now trying to implement the IHttpClientFactory DI as recommended. I am following this article: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-7.0 and I am getting this error:
System.ArgumentNullException: Value cannot be null. (Parameter 'factory')
at System.ThrowHelper.Throw(String paramName)
at System.Net.Http.HttpClientFactoryExtensions.CreateClient(IHttpClientFactory factory)
at DespatchProServer.Pages.Customers.CustomersHome.GetCustomerQuotes(Int32 customerId) in C:\path\to\CustomersHome.razor.cs:line 246
at my.dot.notation.CustomersHome.CustomerRowSelectHandler(RowSelectEventArgs`1 args) in C:\path\to\CustomersHome.razor.cs:line 137
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Syncfusion.Blazor.Grids.Internal.Selection`1.SelectByRow(Row`1 rowToSelect, MouseAndKeyArgs evt)
at Syncfusion.Blazor.Grids.Internal.Selection`1.ValidateRowSelectionClick(Row`1 row, MouseAndKeyArgs e)
at Syncfusion.Blazor.Grids.Internal.Selection`1.RowSelectionClickHandler(MouseAndKeyArgs e, ValueTuple`3 target)
at Syncfusion.Blazor.Grids.Internal.Selection`1.ClickHandler(MouseEventArgs e, ValueTuple`3 target)
at Syncfusion.Blazor.Grids.Internal.GridCellBase`1.CellClickHandler(MouseEventArgs e, Boolean IsCheckBox)
at Syncfusion.Blazor.Grids.Internal.GridCell`1.<BuildRenderTree>b__0_5(MouseEventArgs e)
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
In Program.cs I have:
builder.Services.AddHttpClient();
And here is my minimum reproducible code:
public partial class CustomersHome
{
private readonly IHttpClientFactory _httpClientFactory;
public CustomersHome() { }
public CustomersHome(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;
public IEnumerable<Quotation> customerQuotations = Array.Empty<Quotation>();
public async Task CustomerRowSelectHandler(RowSelectEventArgs<Customer> args)
{
await GetCustomerQuotes(args.Data.customerId);
}
public async ValueTask GetCustomerQuotes(int customerId)
{
string url = string.Format(@"https://my.server.dns/quotations/customer/{0}", customerId);
var httpRequestMessage = new HttpRequestMessage(
HttpMethod.Get,
url)
{
Headers =
{
{ HeaderNames.Accept, "application/vnd.github.v3+json" },
{ HeaderNames.UserAgent, "HttpRequestsSample" }
}
};
var httpClient = _httpClientFactory.CreateClient(); **-> This is line 246**
HttpResponseMessage response = await httpClient.SendAsync(httpRequestMessage);
if (response.IsSuccessStatusCode)
{
customerQuotations = await response.Content.ReadFromJsonAsync<IEnumerable<Quotation>>() ?? Enumerable.Empty<Quotation>(); ;
}
}
}
The call comes from a Syncfusion Grid on row select, not that I think that has any bearing on the outcome. Any pointers gratefully received.
Upvotes: 0
Views: 1710
Reputation: 653
OK, got to the bottom of this. Bear in mind, I am not a developer, so don't laugh too much at me. On my razor page, added:
@inject IHttpClientFactory ClientFactory
Then on my code behind page changed the line:
var httpClient = _httpClientFactory.CreateClient();
To
var httpClient = ClientFactory.CreateClient();
and removed the constructors at the top of the class. Working perfectly now.
Upvotes: 1