跳到主要内容

6.2.3 Blazor 路由与 API Client

Blazor 页面通过 @page 定义路由,通过 HttpClient 调用后端 API。把 API 调用封装成 Client,可以避免页面组件里充满请求细节。

学习目标

  • 能定义 Blazor 页面路由和路由参数。
  • 能使用 NavigationManager 做页面跳转。
  • 能封装类型化 API Client。
  • 能处理加载、空状态和错误状态。

应用场景

  • /todos 展示任务列表。
  • /todos/{id:int} 展示任务详情。
  • 创建成功后跳转到详情页。
  • 统一处理 API 错误提示。

路由示例

@page "/todos/{Id:int}"

<h1>任务详情</h1>

@if (todo is null)
{
<p>加载中...</p>
}
else
{
<h2>@todo.Title</h2>
<p>@todo.Description</p>
}

@code {
[Parameter]
public int Id { get; set; }

private TodoDetailDto? todo;

protected override async Task OnParametersSetAsync()
{
todo = await TodoApi.GetByIdAsync(Id);
}
}

API Client 示例

public sealed class TodoApiClient(HttpClient httpClient)
{
public async Task<IReadOnlyList<TodoListItemDto>> GetTodosAsync(
CancellationToken cancellationToken = default)
{
var todos = await httpClient.GetFromJsonAsync<List<TodoListItemDto>>(
"/todos",
cancellationToken);

return todos ?? [];
}

public async Task<TodoDetailDto?> GetByIdAsync(
int id,
CancellationToken cancellationToken = default)
{
var response = await httpClient.GetAsync($"/todos/{id}", cancellationToken);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return null;
}

response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<TodoDetailDto>(cancellationToken);
}
}

服务注册

builder.Services.AddScoped(sp =>
new HttpClient
{
BaseAddress = new Uri(builder.Configuration["ApiBaseUrl"]!),
});

builder.Services.AddScoped<TodoApiClient>();

重点难点

  • 页面组件负责 UI 状态,API Client 负责请求细节。
  • 路由参数变化时使用 OnParametersSetAsync,不要只依赖初始化。
  • API Base URL 不要硬编码到组件中。
  • 后端错误要映射为用户能理解的 UI 状态。

常见误区

误区推荐做法
每个页面重复写 HttpClient 调用封装类型化 API Client
路由参数变化页面不刷新OnParametersSetAsync 加载数据
只展示加载状态同时处理空状态、错误和重试

练习

  • 为任务详情页增加 404 空状态。
  • 创建任务成功后跳转到详情页。
  • 把 API Base URL 移到配置文件。

延伸阅读

  • Blazor routing。
  • Blazor HttpClient。
  • Blazor 生命周期方法。