Практикум WPF — сервер ASP.NET Core Web API
Практикум, шаг 3 из 6. Поднимаем TaskDesk.Api — REST-сервер для десктоп-клиента. Базовый цикл ASP.NET — Первая программа на ASP.NET Core; Minimal API — Minimal API и OpenAPI; REST — REST.
Контракт API
Ресурс — задача (Task). Базовый префикс /api/v1/tasks.
| Метод | URL | Тело | Ответ |
|---|---|---|---|
GET | /api/v1/tasks | — | 200 массив TaskDto |
GET | /api/v1/tasks/{id} | — | 200 или 404 |
POST | /api/v1/tasks | { "title", "status" } | 201 + Location |
PUT | /api/v1/tasks/{id} | полный TaskDto | 200 или 404 |
DELETE | /api/v1/tasks/{id} | — | 204 или 404 |
Фильтр (опционально): GET /api/v1/tasks?status=Todo.
Структура проекта
mkdir TaskDesk
cd TaskDesk
dotnet new sln -n TaskDesk
dotnet new webapi -n TaskDesk.Api -o src/TaskDesk.Api --use-controllers
dotnet new classlib -n TaskDesk.Core -o src/TaskDesk.Core
dotnet sln add src/TaskDesk.Api src/TaskDesk.Core
dotnet add src/TaskDesk.Api reference src/TaskDesk.Core
TaskDesk/
├── TaskDesk.sln
└── src/
├── TaskDesk.Api/
│ ├── Program.cs
│ ├── Controllers/TasksController.cs
│ └── Services/InMemoryTaskStore.cs
└── TaskDesk.Core/
├── Models/TaskItem.cs
└── Contracts/TaskDto.cs
DTO — контракт JSON
namespace TaskDesk.Core.Contracts;
public record TaskDto(
Guid Id,
string Title,
string Status,
DateTimeOffset CreatedAt);
public record CreateTaskRequest(string Title, string Status = "Todo");
public record UpdateTaskRequest(string Title, string Status);
DTO отделены от доменной модели — клиент WPF и тесты завязаны на стабильный JSON, а не на внутренние классы сервера.
Хранилище и DI
Код ITЗагрузка примера кода…
Регистрация в Program.cs:
builder.Services.AddSingleton<ITaskStore, InMemoryTaskStore>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
Для учебного проекта достаточно памяти; прод-вариант — EF Core + SQLite (Приложение с S3, PostgreSQL и ASP.NET Core Web API).
Контроллер REST
Код ITЗагрузка примера кода…
Program.cs — pipeline, Swagger, CORS
Десктоп-клиент на другом origin (или localhost с другим портом) требует CORS:
Код ITЗагрузка примера кода…
WPF-приложение не является браузером — HttpClient не применяет CORS так же, как Chrome. Политика CORS нужна, если клиент ходит через WebView или вы тестируете из Swagger/браузера. Для чистого HttpClient из WPF достаточно корректного URL и TLS; CORS оставляем для единообразия с веб-инструментами и будущим Blazor Hybrid.
Запуск:
cd src/TaskDesk.Api
dotnet run --urls http://localhost:5100
Swagger UI: http://localhost:5100/swagger.
Проверка вручную
curl -X GET http://localhost:5100/api/v1/tasks
curl -X POST http://localhost:5100/api/v1/tasks `
-H "Content-Type: application/json" `
-d "{\"title\":\"Настроить Prism\"}"
Ожидаем 201 и JSON с id.
Ошибки и коды
| Код | Когда |
|---|---|
400 | Пустой заголовок, неверный enum статуса |
404 | Нет задачи с таким id |
500 | Необработанное исключение — логируем, клиенту краткий JSON |
Единый формат ошибки упрощает отображение в WPF (ErrorMessage в ViewModel).
Чек-лист шага 3
- API отвечает на
GETиPOST/api/v1/tasks. - Swagger открывается в Development.
- DTO в
TaskDesk.Coreсовпадают с тем, что ожидает клиент. - Сервис зарегистрирован через DI.
Дальше: Клиент WPF на Prism.