跳到主要内容

7.1 实战目标与 API 契约

学习目标​

  • 把绑定、命令、异步和依赖注入组合成一个完整客户端。
  • 明确 View、ViewModel 和 API 各自负责的状态。
  • 根据契约判断一次操作应产生什么请求和界面变化。

交付什么​

TaskDesk 是本机任务管理示例:查询列表、输入标题新增、完成所选、删除所选、取消当前请求。状态栏显示正在执行、成功、取消或错误;请求期间窗口仍能响应。客户端用只读 DataGrid 显示结果,通过命令发起修改,避免把编辑中的行误当作已保存的数据。

完整源码在本地 examples/TaskDesk,运行说明是其中的 README.md。网页正文保留关键代码;站点部署本身不会发布这些源码为下载文件。请在本地仓库打开该目录。需要先掌握 DataContext、命令 和 异步线程。

从后端经验建立边界​

层对应源码责任
ViewMainWindow.xaml布局、绑定、选择和交互展示
ViewModelViewModels/MainViewModel.cs列表、输入、忙碌状态、命令和错误提示
客户端服务Services/ITodoService.cs、TodoService.csHTTP、JSON、状态码转换
APITaskDesk.Api/Program.cs接收请求、校验标题、返回状态码
内存存储TaskDesk.Api/Services/TodoStore.cs用锁保护读写并返回不可变记录

ViewModel 不是 Controller:它在窗口存活期间持续保存 UI 状态。HTTP 请求结束不会销毁它,选中项和输入仍然存在。API 则不认识窗口里的选择,也不能信任客户端按钮的禁用状态。客户端校验帮助用户输入,服务端仍然负责验证每个请求。

确定契约​

下面是完整模型声明,分别放入 API 的 Models/TodoDto.cs 和客户端同名文件时,需要使用对应命名空间;本地源码已经提供这两个文件。

客户端 Models/TodoDto.cs
namespace TaskDesk.Client.Models;

public sealed record TodoDto(int Id, string Title, bool IsCompleted);
public sealed record CreateTodoRequest(string Title);
public sealed record UpdateTodoRequest(string Title, bool IsCompleted);

API 的 Web JSON 默认输出 id、title、isCompleted。客户端使用 System.Net.Http.Json 的 Web 默认选项读取,双方不需要共享程序集。

操作HTTP成功结果
刷新GET /api/todos200,任务数组
新增POST /api/todos,仅传 title201,新建 DTO,默认未完成
完成PUT /api/todos/{id},传标题及 isCompleted200,更新后的 DTO
删除DELETE /api/todos/{id}204,无响应体

POST 和 PUT 都先去掉标题首尾空格,再检查非空、最多 120 个 UTF-16 代码单元,否则返回 400 验证问题。PUT 和 DELETE 操作不存在的 ID 返回 404;服务端不把删除不存在的任务伪装成成功。POST 响应的 Location 标识资源,本示例只实现列表 GET,不提供单项 GET。

最小联调步骤​

安装 Windows 上的 .NET 10 SDK 后,在仓库根目录开两个终端。只有运行时无法执行这些项目命令。先启动 API:

dotnet run --project examples/TaskDesk/TaskDesk.Api/TaskDesk.Api.csproj --urls http://localhost:5080

第二个终端查询,再启动 WPF。API 初始返回两条任务,窗口加载时也会自动刷新。

Invoke-RestMethod http://localhost:5080/api/todos
dotnet run --project examples/TaskDesk/TaskDesk.Client/TaskDesk.Client.csproj

常见问题​

为什么重启 API 数据消失? 存储在进程内存,重启恢复初始数据。本例专注客户端机制,数据库属于后续扩展。

桌面调用要开 CORS 吗? WPF 的 HttpClient 不受浏览器同源策略限制,不需要为本机示例添加 CORS。网络地址、证书、认证和服务端授权仍然需要正确配置。

能直接部署到公网吗? 本例没有认证、用户隔离和持久化。HTTP 只用于本机教学,正式服务必须采用可信 HTTPS,并实现服务端授权。

练习与验收​

不打开客户端,使用 PowerShell 新增一条带首尾空格的任务,并查询列表。验收:响应为新 DTO、标题已去空格、isCompleted 为 false;空白标题被拒绝。再说明客户端选中项为何不应加入 GET 请求。接下来进入 实现任务管理客户端。

官方资料​