No description
- CSS 45.3%
- HTML 32.7%
- C# 13.5%
- JavaScript 8.5%
| BlazorDemo.Backend.Api | ||
| BlazorDemo.Frontend.InteractiveServer | ||
| BlazorDemo.Frontend.Shared.Infrastructure | ||
| BlazorDemo.Frontend.Shared.Ui | ||
| .editorconfig | ||
| .gitignore | ||
| BlazorDemo.sln | ||
| README.md | ||
Step 2 - Backend
Prerequisites
basic familiarity with
- dotnet cli
- c#
- blazor
- dependency injection
CLI - Extend the Project Structure
add BlazorDemo.Backend.Api project
dotnet new webapi -minimal -n BlazorDemo.Backend.Api
add BlazorDemo.Frontend.Shared.Infrastructure project (for accessing the API)
dotnet new classlib -n BlazorDemo.Frontend.Shared.Infrastructure
add reference to Infrastructure for InteractiveServer
dotnet reference add BlazorDemo.Frontend.Shared.Infrastructure/BlazorDemo.Frontend.Shared.Infrastructure.csproj --project BlazorDemo.Frontend.InteractiveServer/BlazorDemo.Frontend.InteractiveServer.csproj
add reference to Infrastructure for Ui
dotnet reference add BlazorDemo.Frontend.Shared.Infrastructure/BlazorDemo.Frontend.Shared.Infrastructure.csproj --project BlazorDemo.Frontend.Shared.Ui/BlazorDemo.Frontend.Shared.Ui.csproj
update Solution file
dotnet sln add **/*.csproj
Code - Use the Shared Infrastructure
add BlazorDemo.Frontend.Shared.Infrastructure/TypedHttpClients/HttpWeatherClient.cs
namespace BlazorDemo.Frontend.Shared.Infrastructure.TypedHttpClients;
public class HttpWeatherClient
{
private const string ENDPOINT_URL = "weatherforecast";
private readonly HttpClient _client;
public HttpWeatherClient(HttpClient client)
{
_client = client;
}
public async Task<string> Get()
{
var req = new HttpRequestMessage
{
RequestUri = new Uri(_client.BaseAddress + ENDPOINT_URL),
Method = HttpMethod.Get,
};
var res = await _client.SendAsync(req);
var resContent = await res.Content.ReadAsStringAsync();
if (res.IsSuccessStatusCode is not true)
{
throw new Exception($"{res.StatusCode}: {resContent}");
}
return resContent;
}
}
update BlazorDemo.Frontend.Shared.Ui/_Imports.razor
...
@using BlazorDemo.Frontend.Shared.Infrastructure
@using BlazorDemo.Frontend.Shared.Infrastructure.TypedHttpClients
add BlazorDemo.Frontend.Shared.Ui/WeatherApiComponent.razor
@page "/weatherapi"
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (string.IsNullOrEmpty(response))
{
<p><em>Loading...</em></p>
}
else
{
<p>@response</p>
}
@code {
string response { get; set; }
[Inject]
public HttpWeatherClient HttpWeatherClient { get; set; }
protected override async Task OnInitializedAsync()
{
response = await HttpWeatherClient.Get();
}
}
update BlazorDemo.Frontend.Shared.Ui/CustomLayout.razor
@inherits LayoutComponentBase
...
<article class="customcontent px-2">
<div class="content-center">
<WeatherApiComponent/>
@Body
</div>
</article>
...
update BlazorDemo.Frontend.InteractiveServer/Program.cs
using BlazorDemo.Frontend.Shared.Infrastructure.TypedHttpClients;
...
builder
.Services.AddHttpClient<HttpWeatherClient>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("http://localhost:YOURAPIPORT"));
...
Test
dotnet run --project BlazorDemo.Backend.Api & dotnet watch run --project BlazorDemo.Frontend.InteractiveServer/
- navigate
"/"- works - navigate
"/weatherapi"- 404
Fix 404 error inside BlazorDemo.Frontend.InteractiveServer/Program.cs
using BlazorDemo.Frontend.Shared.Ui;
...
app.MapRazorComponents<App>()
// so pages are recognized
.AddAdditionalAssemblies(typeof(WeatherApiComponent).Assembly)
.AddInteractiveServerRenderMode();
...
We need to explicitely tell
InteractiveServerto discover and use routable blazor components, more information here