2
votes

I want to make Http calls from a service in Blazor rather than making calls in the @code block in the .razor file nor in a code-behind. I receive the error:
Shared/WeatherService.cs(16,17): error CS0246: The type or namespace name 'HttpClient' could not be found (are you missing a using directive or an assembly reference?)

The documentation shows that this is how it's done.

Complex services might require additional services. In the prior example, DataAccess might require the HttpClient default service. @inject (or the InjectAttribute) isn't available for use in services. Constructor injection must be used instead. Required services are added by adding parameters to the service's constructor. When DI creates the service, it recognizes the services it requires in the constructor and provides them accordingly.

Source: https://docs.microsoft.com/en-us/aspnet/core/blazor/dependency-injection?view=aspnetcore-3.0#use-di-in-services

How do I remedy the error?

// WeatherService.cs
using System.Threading.Tasks;

namespace MyBlazorApp.Shared
{
    public interface IWeatherService
    {
        Task<Weather> Get(decimal latitude, decimal longitude);
    }

    public class WeatherService : IWeatherService
    {
        public WeatherService(HttpClient httpClient)
        {
            ...
        }

        public async Task<Weather> Get(decimal latitude, decimal longitude)
        {
            // Do stuff
        }

    }
}
// Starup.cs
using Microsoft.AspNetCore.Components.Builder;
using Microsoft.Extensions.DependencyInjection;
using MyBlazorApp.Shared;

namespace MyBlazorApp
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IWeatherService, WeatherService>();
        }

        public void Configure(IComponentsApplicationBuilder app)
        {
            app.AddComponent<App>("app");
        }
    }
}
2
You are missing using System.Net.Http; to have access to the class in WeatherService.csNkosi
Be clear about Client-side or Server-side Blazor, for HttpClient there are some subtle differences.Henk Holterman
@HenkHolterman Can you elaborate what you're asking? "Client-Side" is in the title of my question for that reason specifically if I understand what you mean. Did I miss something?dapperdan1985
No, I just missed that in the title. Was looking at text & tags.Henk Holterman

2 Answers

4
votes

You are missing using System.Net.Http; to have access to the class in WeatherService.cs

// WeatherService.cs
using System.Threading.Tasks;
using System.Net.Http; //<-- THIS WAS MISSING

namespace MyBlazorApp.Shared {
    public interface IWeatherService {
        Task<Weather> Get(decimal latitude, decimal longitude);
    }

    public class WeatherService : IWeatherService {
        private HttpClient httpClient;

        public WeatherService(HttpClient httpClient) {
            this.httpClient = httpClient;
        }

        public async Task<Weather> Get(decimal latitude, decimal longitude) {
            // Do stuff
        }

    }
}

If using the full name for the class System.Net.Http.HttpClient does not work then you are definitely missing a reference to the assembly.

1
votes

You can configure httpclient in startup.cs.

    services.AddHttpClient();
    services.AddScoped<HttpClient>();

Now you can use HttClient in .razor files.

@inject HttpClient httpClient

-------------

private async Task LoadSystems() => systemsList = await httpClient.GetJsonAsync<List<Models.Systems>>("Systems/GetSystems");