Hur en Blazor-app pratar med ett HTTP API via HttpClient och hur du skyddar sidor med Blazors inbyggda autentiseringsstöd.
AuthorizeView.
// Program.cs
builder.Services.AddHttpClient<ProductApi>(client =>
{
client.BaseAddress = new Uri(builder.Configuration["Api:BaseUrl"]!);
});
// För Blazor Server kan du också använda en generisk:
builder.Services.AddHttpClient();
public class ProductApi
{
private readonly HttpClient _http;
public ProductApi(HttpClient http) => _http = http;
public async Task<List<Product>> GetAllAsync()
=> await _http.GetFromJsonAsync<List<Product>>("products") ?? new();
public async Task<Product?> GetAsync(int id)
=> await _http.GetFromJsonAsync<Product>($"products/{id}");
public async Task<Product> CreateAsync(Product p)
{
var resp = await _http.PostAsJsonAsync("products", p);
resp.EnsureSuccessStatusCode();
return (await resp.Content.ReadFromJsonAsync<Product>())!;
}
public async Task UpdateAsync(int id, Product p)
{
var resp = await _http.PutAsJsonAsync($"products/{id}", p);
resp.EnsureSuccessStatusCode();
}
public async Task DeleteAsync(int id)
{
var resp = await _http.DeleteAsync($"products/{id}");
resp.EnsureSuccessStatusCode();
}
}
@page "/products"
@inject ProductApi Api
<h1>Produkter</h1>
@if (loading)
{
<p>Laddar...</p>
}
else if (error != null)
{
<div class="alert">@error</div>
}
else
{
<ul>
@foreach (var p in products)
{
<li>@p.Name — @p.Price.ToString("C")</li>
}
</ul>
}
@code {
private List<Product> products = new();
private bool loading = true;
private string? error;
protected override async Task OnInitializedAsync()
{
try
{
products = await Api.GetAllAsync();
}
catch (HttpRequestException ex)
{
error = $"Kunde inte hämta produkter: {ex.Message}";
}
finally
{
loading = false;
}
}
}
GetFromJsonAsync, PostAsJsonAsync, PutAsJsonAsync och ReadFromJsonAsync finns i namespace System.Net.Http.Json. De använder System.Text.Json under huven.
private CancellationTokenSource? _cts;
protected override async Task OnInitializedAsync()
{
_cts = new CancellationTokenSource();
try
{
products = await Api.GetAllAsync(_cts.Token);
}
catch (OperationCanceledException) { /* användaren navigerade bort */ }
}
public void Dispose() => _cts?.Cancel();
Blazor har ett inbyggt <ErrorBoundary> som fångar undantag från sina barn:
<ErrorBoundary>
<ChildContent>
<ProductList />
</ChildContent>
<ErrorContent Context="ex">
<div class="alert alert-danger">
<p>Något gick fel: @ex.Message</p>
</div>
</ErrorContent>
</ErrorBoundary>
Blazor använder ASP.NET Cores standard-autentisering. Den vanligaste vägen i en ny app är att skapa projektet med --auth Individual:
dotnet new blazor -o MinApp --interactivity Server --auth Individual
Detta ger dig:
/AccountAuthenticationStateProvider som tjänst i DICascadingAuthenticationState och AuthorizeRouteView i Routes.razor<AuthorizeView>
<Authorized>
<p>Hej, @context.User.Identity?.Name!</p>
<a href="Account/Logout">Logga ut</a>
</Authorized>
<NotAuthorized>
<a href="Account/Login">Logga in</a>
</NotAuthorized>
</AuthorizeView>
<AuthorizeView Roles="Admin">
<a href="/admin">⚙️ Admin</a>
</AuthorizeView>
@page "/admin/dashboard"
@attribute [Authorize(Roles = "Admin")]
<h1>Admin-dashboard</h1>
@inject AuthenticationStateProvider AuthState
@code {
protected override async Task OnInitializedAsync()
{
var state = await AuthState.GetAuthenticationStateAsync();
var user = state.User;
if (user.Identity?.IsAuthenticated == true)
{
var name = user.Identity.Name;
var roles = user.Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value)
.ToList();
}
}
}
AuthorizeView hindrar bara visning. Skydda alltid API-endpoints med [Authorize] på servern också. Klientvalidering är aldrig säkerhet.
.NET 10 har flera målmedvetna förbättringar för säkerhet och HTTP — viktigast för dig som bygger Blazor-appar:
OnRedirectToLogin-handler.
HttpClient. För de flesta JSON-API:er märks ingenting, men om du har gammal kod som läser response.Content efter att HttpClient har gjort sig av med svaret, kan du behöva opta ut: <WasmEnableStreamingResponse>false</WasmEnableStreamingResponse> i .csproj.
Lös övningarna självständigt. Det finns inget facit — lärandet sker i processen.
PostsApi som anropar https://jsonplaceholder.typicode.com/posts. Visa alla inlägg i en lista och låt användaren klicka på ett för att se detaljer.
--auth Individual. Registrera ett konto, logga in/ut och bygg en sida som bara visas för inloggade. Lägg till en roll "Admin" manuellt i databasen och skydda en sida för Admin-roll.
api.open-meteo.com) och visa väderprognos för en stad användaren väljer. Hantera laddning, fel och tom data snyggt.