CanadianMoose
CanadianMoose

Reputation: 31

Add Blazor Client to ASP .Net Core Web API (.NET 6)

I was wondering if there was a specific way to add a Blazor front end to an ASP .NET Core project. I know when creating an Blazor WebAssembly App there is the option to select ASP.Net Core Hosted and it would create a template, but I would like to add the client to the host manually.

Specifically, I've been looking at this ASP.Net to ASP.Net Core tutorial here and would like to add a Blazor front-end to the ASP.NET Core Web API project that is created.

Sorry in advance if the question isn't clear, this is my first time doing this sort of project.

Upvotes: 2

Views: 4369

Answers (1)

clamchoda
clamchoda

Reputation: 4951

If you want to add the API to the host manually you can create an ASP.NET Core Web API project. Create your post/get/ect controllers in the Web API, and in the Blazor Project inject an HttpClient with a BaseUri that points at your Web API controllers.

This is how I set mine up too. I keep all my components and services separate in class library and razor library projects. Let me know if you need further assistance.

Update

Seems like their might be some confusion on the project layout. For this example I named my Blazor Server App BlazorServerFrontEnd. I named my ASP.NET Core Web API BlazorServerBackEnd. I created mine on .NET Core 6.0. It doesn't use a Startup.cs like 3.1. Instead everything is done in the Program.cs file.

enter image description here enter image description here

BlazorServerBackEnd (Web Api) will not have services.AddServerSideBlazor() like our BlazorServerFrontEnd (Blazor Server App). If you're seeing this in both projects you probably selected the wrong type. When you run BlazorServerBackEnd (Web Api) you'll see it has one controller built in (Controllers/WeatherForecastController.cs).

enter image description here

BlazorServerFrontEnd (Blazor Server App) will have services.AddServerSideBlazor(). You'll see in Data folder there is also a WeatherForecatService.cs. When you look at the service it doesn't connect to any Api. The service just grabs the data from a hardcoded readonly string[].

public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet(Name = "GetWeatherForecast")]
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

This is what we need to change. Instead of the data being fetched from within BlazorServerFrontEnd (Blazor Server App) we want to connect to our BlazorServerBackEnd (Web Api). Open up Program.cs in the BlazorServerFrontEnd (Blazor Server App) and change the injected WeatherForecastService from a Singleton to an HttpClient.

//builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddHttpClient<WeatherForecastService>(client =>
{
    // Path pointing to BlazorServerBackEnd (Web Api) baseUri
    client.BaseAddress = new Uri("https://localhost:7246/");
});

Open up WeatherForecastService.cs in the BlazorServerFrontEnd (Blazor Server App) and add a constructor to inject our HttpClient that we just setup. We'll use the HttpClient to connect to our BlazorServerBackEnd (Web Api) using _httpClient.GetAsync("WeatherForecast"). Now it looks like this;

public class WeatherForecastService
{
    private readonly HttpClient _httpClient;
    public WeatherForecastService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }


    public async Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
    {
        var response = await _httpClient.GetAsync("WeatherForecast");

        if (response.IsSuccessStatusCode)
        {
            string json = await response.Content.ReadAsStringAsync();
            WeatherForecast[] forecasts = JsonConvert.DeserializeObject<WeatherForecast[]>(json);
            return forecasts;
        }

        return null;
    }
}

Please keep in mind this is a very brief example to get you on your feet. Ideally you'll want to have an interface for your services, and you'll want to inject the interface into your pages instead of the class. So in the real world it would look more like this;

builder.Services.AddHttpClient<IWeatherForecastService, WeatherForecastService>(client =>
{
    // Path pointing to BlazorServerBackEnd (Web Api) baseUri
    client.BaseAddress = new Uri("https://localhost:7246/");
});

And you would be injecting your interface into the page like so;

@inject IWeatherForecastService ForecastService

I also recommend separating components, services, controllers, models ect. into seperate razor/class libraries. Keep everything very loosely coupled. This will make it easy for you to port your application over to something like a MAUI or Windows Forms App BlazorWebView.

P.S. Swagger comes built into the Web Api project. It is very useful when developing and debugging. I would recommend familiarizing yourself with it if your new.

Upvotes: 2

Related Questions