Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Это не последняя версия этой статьи. В текущей версии смотрите статью о версии .NET 9.
Warning
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии смотрите статью о версии .NET 9.
Important
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущей версии смотрите статью о версии .NET 9.
By Tim Deschryver and Rick Anderson
В этом руководстве описаны основы создания веб-API на основе контроллера, использующего базу данных. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. См. Руководство: Создание минимального API с помощью ASP.NET Core для получения инструкции по созданию минимального API.
Overview
В этом руководстве создается следующий API-интерфейс:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Получение всех элементов задач | None | Массив задач |
GET /api/todoitems/{id} |
Получение элемента по идентификатору | None | To-do item |
POST /api/todoitems |
Добавление нового элемента | To-do item | To-do item |
PUT /api/todoitems/{id} |
Обновление существующего элемента | To-do item | None |
DELETE /api/todoitems/{id} |
Удаление элемента | None | None |
На следующем рисунке показана структура приложения.
Prerequisites
Visual Studio 2022 с рабочей нагрузкой ASP.NET и веб-разработка.
Создание проекта веб-API
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Выберите шаблон Веб-API ASP.NET Core и нажмите кнопку Далее.
- В диалоговом окне Настроить новый проект присвойте проекту имя TodoApi и нажмите кнопку Далее.
- In the Additional information dialog:
- Confirm the Framework is .NET 9.0 (Standard Term Support).
- Убедитесь, что установлен флажок для включения поддержки OpenAPI.
- Убедитесь, что установлен флажок для Использовать контроллеры (снимите флажок, чтобы использовать минимальные API).
- Select Create.
Добавление пакета NuGet
Пакет NuGet необходимо добавить для поддержки базы данных, используемой в этом руководстве.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Confirm correct package versions at NuGet.org.
Запуск проекта
The project template creates a WeatherForecast
API with support for OpenAPI.
Нажмите клавиши CTRL+F5, чтобы выполнить запуск без отладчика.
Visual Studio отображает следующее диалоговое окно, если проект еще не настроен для использования SSL:
Select Yes if you trust the IIS Express SSL certificate.
Отобразится следующее диалоговое окно.
Select Yes if you agree to trust the development certificate.
Сведения о доверии к браузеру Firefox см. в разделе Ошибка сертификата браузера Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio запускает окно терминала и отображает URL-адрес работающего приложения. API размещается в https://localhost:<port>
, где <port>
является случайным образом выбранным номером порта при создании проекта.
...
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:7260
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:7261
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
...
Ctrl+click the HTTPS URL in the output to test the web app in a browser. Конечная точка https://localhost:<port>
отсутствует, поэтому браузер возвращает HTTP 404 Not Found.
Добавьте /weatherforecast
в URL-адрес для тестирования API WeatherForecast.
В браузере отображается JSON, аналогичный следующему примеру:
[
{
"date": "2025-07-16",
"temperatureC": 52,
"temperatureF": 125,
"summary": "Mild"
},
{
"date": "2025-07-17",
"temperatureC": 36,
"temperatureF": 96,
"summary": "Warm"
},
{
"date": "2025-07-18",
"temperatureC": 39,
"temperatureF": 102,
"summary": "Cool"
},
{
"date": "2025-07-19",
"temperatureC": 10,
"temperatureF": 49,
"summary": "Bracing"
},
{
"date": "2025-07-20",
"temperatureC": -1,
"temperatureF": 31,
"summary": "Chilly"
}
]
Тестирование проекта
В этом руководстве для тестирования API используются обозреватель конечных точек и HTTP-файлы .
Добавление класса модели
A model is a set of classes that represent the data that the app manages. Для этого приложения используется класс модели TodoItem
.
- In Solution Explorer, right-click the project. Select Add>New Folder. Назовите папку
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - Замените код шаблона следующим кодом:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Свойство Id
выступает в качестве уникального ключа реляционной базы данных.
Классы моделей можно размещать в любом месте проекта, но обычно для этого используется папка Models
.
Добавление контекста базы данных
The database context is the main class that coordinates Entity Framework functionality for a data model. Этот класс является производным от класса Microsoft.EntityFrameworkCore.DbContext.
Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.Введите следующий код:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Регистрация контекста базы данных
В ASP.NET Core службы (такие как контекст базы данных) должны быть зарегистрированы с помощью контейнера внедрения зависимостей. Контейнер предоставляет службу контроллерам.
Обновите Program.cs
, используя выделенный код:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddOpenApi();
builder.Services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Предыдущий код:
- Добавляет
using
директивы. - Добавляет контекст базы данных в контейнер внедрения зависимостей.
- Указывает, что контекст базы данных будет использовать базу данных в памяти.
Создание каркаса контроллера
Щелкните правой кнопкой мыши папку
Controllers
.Select Add>New Scaffolded Item.
Выберите Контроллер API с действиями, использующий Entity Framework, а затем выберите Добавить.
В диалоговом окне Добавить контроллер API с действиями, используя Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
На этом шаге в проект добавляются Microsoft.VisualStudio.Web.CodeGeneration.Design
и Microsoft.EntityFrameworkCore.Tools
пакеты NuGet.
Эти пакеты необходимы для создания каркаса.
Сформированный код:
- Пометьте этот класс атрибутом
[ApiController]
. Этот атрибут указывает, что контроллер отвечает на запросы веб-API. Дополнительные сведения о поведении, которое реализует этот атрибут, см. в статье Создание веб-API с помощью ASP.NET Core. - Использует DI для инъекции контекста базы данных (
TodoContext
) в контроллер. The database context is used in each of the CRUD methods in the controller.
Шаблоны ASP.NET Core для:
- Контроллеры с представлениями включают
[action]
в шаблоне маршрута. - Контроллеры API не включают
[action]
в шаблоне маршрута.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. То есть имя связанного метода действия не используется в соответствующем маршруте.
Обновление метода создания PostTodoItem
Update the return statement in the PostTodoItem
to use the nameof operator:
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
// return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}
Предыдущий код является методом HTTP POST
, как указано атрибутом [HttpPost]
. Метод получает значение TodoItem
из текста HTTP-запроса.
Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
Метод CreatedAtAction:
- В случае успеха возвращает код состояния HTTP 201.
HTTP 201
— это стандартныйHTTP POST
ответ для метода, создающего новый ресурс на сервере. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Дополнительные сведения см. в разделе 10.2.2 201 «Создан ресурс». - Указывает действие
GetTodoItem
для создания URI заголовкаLocation
. Ключевое словоnameof
C# используется для предотвращения жесткого программирования имени действия в вызовеCreatedAtAction
.
Test PostTodoItem
Select View>Other Windows>Endpoints Explorer.
Right-click the POST endpoint and select Generate request.
Новый файл создается в папке
TodoApi.http
проекта с содержимым, аналогичным следующему примеру:@TodoApi_HostAddress = https://localhost:49738 POST {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { //TodoItem } ###
- Первая строка создает переменную, используемую для всех конечных точек.
- Следующая строка определяет запрос POST.
- Строки после строки запроса POST определяют заголовки и заполнитель для текста запроса.
- Тройной хэштег (
###
) — это разделитель запросов: то, что следует после него, предназначено для другого запроса.
Запрос POST ожидает
TodoItem
. Чтобы определить задачу, замените комментарий//TodoItem
следующим JSON:{ "name": "walk dog", "isComplete": true }
Теперь файл TodoApi.http должен выглядеть следующим образом, но с номером порта:
@TodoApi_HostAddress = https://localhost:7260 Post {{TodoApi_HostAddress}}/api/todoitems Content-Type: application/json { "name": "walk dog", "isComplete": true } ###
Запустите приложение.
Select the Send request link that is above the
POST
request line.The POST request is sent to the app and the response is displayed in the Response pane.
Тестирование URI заголовка поля 'Location'
Test the app by calling the GET
endpoints from a browser or by using Endpoints Explorer. The following steps are for Endpoints Explorer.
In Endpoints Explorer, right-click the first GET endpoint, and select Generate request.
В файл добавляется следующее содержимое
TodoApi.http
:GET {{TodoApi_HostAddress}}/api/todoitems ###
Select the Send request link that is above the new
GET
request line.The GET request is sent to the app and the response is displayed in the Response pane.
Текст ответа аналогичен следующему json:
[ { "id": 1, "name": "walk dog", "isComplete": true } ]
In Endpoints Explorer, right-click the
/api/todoitems/{id}
GET endpoint and select Generate request. В файл добавляется следующее содержимоеTodoApi.http
:@id=0 GET {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Назначьте
{@id}
на1
(вместо0
).Select the Send request link that is above the new GET request line.
The GET request is sent to the app and the response is displayed in the Response pane.
Текст ответа аналогичен следующему json:
{ "id": 1, "name": "walk dog", "isComplete": true }
Знакомство с методами GET
Реализуются две конечные точки GET:
GET /api/todoitems
GET /api/todoitems/{id}
В предыдущем разделе показан пример /api/todoitems/{id}
маршрута.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Это приложение использует базу данных в оперативной памяти. Если приложение остановлено и запущено, предыдущий запрос GET не возвращает никаких данных. If no data is returned, POST data to the app.
Маршрутизация и пути URL
Атрибут [HttpGet]
обозначает метод, который отвечает на HTTP GET
запрос. Путь URL для каждого метода формируется следующим образом:
Начните с строки шаблона в атрибуте
Route
контроллера.[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Замените
[controller]
именем контроллера (по соглашению это имя класса контроллера без суффикса "Controller"). For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Если атрибут
[HttpGet]
имеет шаблон маршрута (например,[HttpGet("products")]
), добавьте его к пути. В этом примере шаблон не используется. Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
В следующем методе GetTodoItem
"{id}"
— это переменная-заполнитель для уникального идентификатора элемента задачи. При вызове GetTodoItem
, значение "{id}"
из URL-адреса передаётся методу через параметр id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Тип возвращаемого значения для методов GetTodoItems
и GetTodoItem
— ActionResult<T>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. Необработанные исключения преобразуются в ошибки 5xx.
Типы возвращаемых значений ActionResult
могут представлять широкий спектр кодов состояний HTTP. Например, метод GetTodoItem
может возвращать два разных значения состояния:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- В противном случае метод возвращает код 200 с телом ответа JSON. Результаты
item
приводят к ответуHTTP 200
.
Метод PutTodoItem
Изучите метод PutTodoItem
:
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
if (id != todoItem.Id)
{
return BadRequest();
}
_context.Entry(todoItem).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
PutTodoItem
аналогичен PostTodoItem
, за исключением того, что он использует HTTP PUT
. Ответ — 204 (Нет содержимого). Согласно спецификации HTTP, PUT
запрос требует от клиента отправки всей обновленной сущности, а не только изменений. To support partial updates, use HTTP PATCH.
Тестирование метода PutTodoItem
В этом примере используется база данных в памяти, которая должна быть инициирована при каждом запуске приложения. При выполнении вызова PUT в базе данных уже должен существовать какой-либо элемент. Для этого перед вызовом PUT выполните вызов GET, чтобы убедиться в наличии такого элемента в базе данных.
Используйте метод PUT
для обновления TodoItem
с идентификатором = 1 и задайте для него значение "feed fish"
. Обратите внимание, что ответ равен HTTP 204 No Content
.
In Endpoints Explorer, right-click the PUT endpoint, and select Generate request.
В файл добавляется следующее содержимое
TodoApi.http
:PUT {{TodoApi_HostAddress}}/api/todoitems/{{id}} Content-Type: application/json { //TodoItem } ###
В строке запроса PUT замените
{{id}}
на1
.Замените заполнитель
//TodoItem
следующими строками:PUT {{TodoApi_HostAddress}}/api/todoitems/1 Content-Type: application/json { "id": 1, "name": "feed fish", "isComplete": false }
Select the Send request link that is above the new PUT request line.
The PUT request is sent to the app and the response is displayed in the Response pane. Текст ответа пуст, а код состояния — 204.
Метод DeleteTodoItem
Изучите метод DeleteTodoItem
:
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
Тестирование метода DeleteTodoItem
Используйте метод DELETE
для удаления TodoItem
с идентификатором = 1. Обратите внимание, что ответ равен HTTP 204 No Content
.
In Endpoints Explorer, right-click the DELETE endpoint and select Generate request.
Запрос DELETE добавляется в
TodoApi.http
.Замените
{{id}}
строку запроса DELETE на1
. Запрос DELETE должен выглядеть следующим образом:DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}} ###
Select the Send request link for the DELETE request.
The DELETE request is sent to the app and the response is displayed in the Response pane. Текст ответа пуст, а код состояния — 204.
Тестирование с помощью других средств
Существует множество других средств, которые можно использовать для тестирования веб-API, например:
Prevent over-posting
В настоящее время пример приложения предоставляет весь объект TodoItem
. Рабочие приложения обычно ограничивают вводимые данные и возвращают их с помощью подмножества модели. Такое поведение реализовано по нескольким причинам, но в основном из соображений безопасности. Подмножество модели обычно называется объектом передачи данных (DTO), моделью ввода или моделью представления.
DTO is used in this tutorial.
DTO можно использовать для следующего:
- Prevent over-posting.
- Скрытие свойств, которые не предназначены для просмотра клиентами.
- Пропуск некоторых свойств, чтобы уменьшить размер полезной нагрузки.
- Уплощение графов объектов, которые содержат вложенные объекты. Сведенные графы объектов могут быть удобнее для клиентов.
Чтобы продемонстрировать подход с применением DTO, обновите класс TodoItem
, включив в него поле секрета:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
Поле секрета должно быть скрыто в этом приложении, однако административное приложение может отобразить его.
Убедитесь, что вы можете отправить и получить секретное поле.
Create a DTO model in a Models/TodoItemsDTO.cs file:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Обновите TodoItemsController
, так чтобы использовать TodoItemDTO
:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
namespace TodoApi.Controllers;
[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
{
private readonly TodoContext _context;
public TodoItemsController(TodoContext context)
{
_context = context;
}
// GET: api/TodoItems
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
return await _context.TodoItems
.Select(x => ItemToDTO(x))
.ToListAsync();
}
// GET: api/TodoItems/5
// <snippet_GetByID>
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return ItemToDTO(todoItem);
}
// </snippet_GetByID>
// PUT: api/TodoItems/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Update>
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
{
if (id != todoDTO.Id)
{
return BadRequest();
}
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
todoItem.Name = todoDTO.Name;
todoItem.IsComplete = todoDTO.IsComplete;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
return NoContent();
}
// </snippet_Update>
// POST: api/TodoItems
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Create>
[HttpPost]
public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
{
var todoItem = new TodoItem
{
IsComplete = todoDTO.IsComplete,
Name = todoDTO.Name
};
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
return CreatedAtAction(
nameof(GetTodoItem),
new { id = todoItem.Id },
ItemToDTO(todoItem));
}
// </snippet_Create>
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
private bool TodoItemExists(long id)
{
return _context.TodoItems.Any(e => e.Id == id);
}
private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
new TodoItemDTO
{
Id = todoItem.Id,
Name = todoItem.Name,
IsComplete = todoItem.IsComplete
};
}
Убедитесь, что вы не можете отправить или получить секретное поле.
Вызов веб-API с помощью JavaScript
См. руководство: Вызов веб-API ASP.NET Core с помощью JavaScript.
Серия видеороликов по веб-API
Смотрите Видео: Серия для начинающих: Web API.
Шаблоны корпоративных веб-приложений
Рекомендации по созданию надежного, безопасного, производительного, тестового и масштабируемого приложения ASP.NET Core см. в шаблонах веб-приложений Enterprise. Полный пример веб-приложения с высоким качеством рабочей среды, реализующий шаблоны, доступен.
Добавление поддержки аутентификации в веб-API
ASP.NET Core Identity позволяет использовать функцию входа в пользовательском интерфейсе для веб-приложений ASP.NET Core. Чтобы защитить веб-API и SPA, используйте один из следующих способов:
Duende Identity Server — это платформа OpenID Connect и OAuth 2.0 для ASP.NET Core. Duende Identity Server включает следующие функции безопасности:
- Проверка подлинности как услуга (AaaS)
- Единый вход и выход (SSO) для различных типов приложений
- Контроль доступа для API
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Дополнительные сведения см. в статье "Миграция из ASP.NET Core в .NET 5 в .NET 6".
Дополнительные сведения см. в документации по Duende Identity Server (на веб-сайте ПО Duende).
Публикация в Azure
Сведения о развертывании в Azure см. в разделе Краткое руководство. Развертывание веб-приложения ASP.NET.
Additional resources
Просмотреть или скачать пример кода для этого учебника. См. раздел Практическое руководство. Скачивание файла.
Дополнительные сведения см. на следующих ресурсах:
- Создание веб-API с помощью ASP.NET Core
- Руководство. Создание минимального API с помощью ASP.NET Core
- Использование созданных документов OpenAPI
- документация по веб-API ASP.NET Core с помощью Swagger / OpenAPI
- Razor
- Маршрутизация на действия контроллера в ASP.NET Core
- Типы возвращаемых действий контроллера в веб-API ASP.NET Core
- Развертывание приложений ASP.NET Core в Службе приложений Azure
- Размещение и развертывание ASP.NET Core
- Создание веб-API с помощью ASP.NET Core
В этом руководстве описаны основы создания веб-API на основе контроллера, использующего базу данных. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. См. Руководство: Создание минимального API с помощью ASP.NET Core для получения инструкции по созданию минимального API.
Overview
В этом руководстве создается следующий API-интерфейс:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Получение всех элементов задач | None | Массив задач |
GET /api/todoitems/{id} |
Получение элемента по идентификатору | None | To-do item |
POST /api/todoitems |
Добавление нового элемента | To-do item | To-do item |
PUT /api/todoitems/{id} |
Обновление существующего элемента | To-do item | None |
DELETE /api/todoitems/{id} |
Удаление элемента | None | None |
На следующем рисунке показана структура приложения.
Prerequisites
Visual Studio 2022 с рабочей нагрузкой ASP.NET и веб-разработка.
Создание веб-проекта
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Выберите шаблон Веб-API ASP.NET Core и нажмите кнопку Далее.
- В диалоговом окне Настроить новый проект присвойте проекту имя TodoApi и нажмите кнопку Далее.
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- Убедитесь, что флажок Use controllers (uncheck to use minimal APIs) (Использовать контроллеры (снимите этот флажок для использования минимальных API)) установлен.
- Убедитесь, что установлен флажок для включения поддержки OpenAPI.
- Select Create.
Добавление пакета NuGet
Пакет NuGet необходимо добавить для поддержки базы данных, используемой в этом руководстве.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Confirm correct package versions at NuGet.org.
Тестирование проекта
The project template creates a WeatherForecast
API with support for Swagger.
Нажмите клавиши CTRL+F5, чтобы выполнить запуск без отладчика.
Visual Studio отображает следующее диалоговое окно, если проект еще не настроен для использования SSL:
Select Yes if you trust the IIS Express SSL certificate.
Отобразится следующее диалоговое окно.
Select Yes if you agree to trust the development certificate.
Сведения о доверии к браузеру Firefox см. в разделе Ошибка сертификата браузера Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio запускает браузер по умолчанию и переходит по адресу https://localhost:<port>/swagger/index.html
, где <port>
— случайно выбранный номер порта при создании проекта.
Откроется страница Swagger /swagger/index.html
. Select GET>Try it out>Execute. На странице отобразятся:
- The Curl command to test the WeatherForecast API.
- URL-адрес для тестирования API WeatherForecast;
- код, текст и заголовки ответа;
- Раскрывающийся список с типами носителей, а также пример значений и схемы.
Если страница Swagger не отображается, см. эту проблему на сайте GitHub.
Swagger используется для создания полезной документации и страниц справки для веб-API. В этом руководстве используется Swagger для тестирования приложения. Дополнительные сведения о Swagger см. в статье Документация по веб-API ASP.NET Core с использованием Swagger (OpenAPI).
Copy and paste the Request URL in the browser: https://localhost:<port>/weatherforecast
Возвращаемые данные JSON будут примерно такими:
[
{
"date": "2019-07-16T19:04:05.7257911-06:00",
"temperatureC": 52,
"temperatureF": 125,
"summary": "Mild"
},
{
"date": "2019-07-17T19:04:05.7258461-06:00",
"temperatureC": 36,
"temperatureF": 96,
"summary": "Warm"
},
{
"date": "2019-07-18T19:04:05.7258467-06:00",
"temperatureC": 39,
"temperatureF": 102,
"summary": "Cool"
},
{
"date": "2019-07-19T19:04:05.7258471-06:00",
"temperatureC": 10,
"temperatureF": 49,
"summary": "Bracing"
},
{
"date": "2019-07-20T19:04:05.7258474-06:00",
"temperatureC": -1,
"temperatureF": 31,
"summary": "Chilly"
}
]
Добавление класса модели
A model is a set of classes that represent the data that the app manages. Для этого приложения используется класс модели TodoItem
.
- In Solution Explorer, right-click the project. Select Add>New Folder. Назовите папку
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - Замените код шаблона следующим кодом:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Свойство Id
выступает в качестве уникального ключа реляционной базы данных.
Классы моделей можно размещать в любом месте проекта, но обычно для этого используется папка Models
.
Добавление контекста базы данных
The database context is the main class that coordinates Entity Framework functionality for a data model. Этот класс является производным от класса Microsoft.EntityFrameworkCore.DbContext.
- Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.
Введите следующий код:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Регистрация контекста базы данных
В ASP.NET Core службы (такие как контекст базы данных) должны быть зарегистрированы с помощью контейнера внедрения зависимостей. Контейнер предоставляет службу контроллерам.
Обновите Program.cs
, используя выделенный код:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Предыдущий код:
- Добавляет
using
директивы. - Добавляет контекст базы данных в контейнер внедрения зависимостей.
- Указывает, что контекст базы данных будет использовать базу данных в памяти.
Создание каркаса контроллера
Щелкните правой кнопкой мыши папку
Controllers
.Select Add>New Scaffolded Item.
Выберите Контроллер API с действиями, использующий Entity Framework, а затем выберите Добавить.
В диалоговом окне Добавить контроллер API с действиями, используя Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
Сформированный код:
- Пометьте этот класс атрибутом
[ApiController]
. Этот атрибут указывает, что контроллер отвечает на запросы веб-API. Дополнительные сведения о поведении, которое реализует этот атрибут, см. в статье Создание веб-API с помощью ASP.NET Core. - Использует DI для инъекции контекста базы данных (
TodoContext
) в контроллер. The database context is used in each of the CRUD methods in the controller.
Шаблоны ASP.NET Core для:
- Контроллеры с представлениями включают
[action]
в шаблоне маршрута. - Контроллеры API не включают
[action]
в шаблоне маршрута.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. То есть имя связанного метода действия не используется в соответствующем маршруте.
Обновление метода создания PostTodoItem
Update the return statement in the PostTodoItem
to use the nameof operator:
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
// return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}
Предыдущий код является методом HTTP POST
, как указано атрибутом [HttpPost]
. Метод получает значение TodoItem
из текста HTTP-запроса.
Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
Метод CreatedAtAction:
- В случае успеха возвращает код состояния HTTP 201.
HTTP 201
— это стандартныйHTTP POST
ответ для метода, создающего новый ресурс на сервере. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Дополнительные сведения см. в разделе 10.2.2 201 «Создан ресурс». - Указывает действие
GetTodoItem
для создания URI заголовкаLocation
. Ключевое словоnameof
C# используется для предотвращения жесткого программирования имени действия в вызовеCreatedAtAction
.
Test PostTodoItem
Нажмите клавиши CTRL+F5, чтобы запустить приложение.
In the Swagger browser window, select POST /api/TodoItems, and then select Try it out.
In the Request body input window, update the JSON. For example,
{ "name": "walk dog", "isComplete": true }
Select Execute
Тестирование URI заголовка поля 'Location'
In the preceding POST, the Swagger UI shows the location header under Response headers. Например, location: https://localhost:7260/api/TodoItems/1
. Заголовок расположения отображает универсальный код ресурса (URI) для созданного ресурса.
Чтобы проверить заголовок расположения, выполните следующие действия.
In the Swagger browser window, select GET /api/TodoItems/{id}, and then select Try it out.
Enter
1
in theid
input box, and then select Execute.
Знакомство с методами GET
Реализуются две конечные точки GET:
GET /api/todoitems
GET /api/todoitems/{id}
В предыдущем разделе показан пример /api/todoitems/{id}
маршрута.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Это приложение использует базу данных в оперативной памяти. Если приложение остановлено и запущено, предыдущий запрос GET не возвращает никаких данных. If no data is returned, POST data to the app.
Маршрутизация и пути URL
Атрибут [HttpGet]
обозначает метод, который отвечает на HTTP GET
запрос. Путь URL для каждого метода формируется следующим образом:
Начните с строки шаблона в атрибуте
Route
контроллера.[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Замените
[controller]
именем контроллера (по соглашению это имя класса контроллера без суффикса "Controller"). For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Если атрибут
[HttpGet]
имеет шаблон маршрута (например,[HttpGet("products")]
), добавьте его к пути. В этом примере шаблон не используется. Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
В следующем методе GetTodoItem
"{id}"
— это переменная-заполнитель для уникального идентификатора элемента задачи. При вызове GetTodoItem
, значение "{id}"
из URL-адреса передаётся методу через параметр id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Тип возвращаемого значения для методов GetTodoItems
и GetTodoItem
— ActionResult<T>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. Необработанные исключения преобразуются в ошибки 5xx.
Типы возвращаемых значений ActionResult
могут представлять широкий спектр кодов состояний HTTP. Например, метод GetTodoItem
может возвращать два разных значения состояния:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- В противном случае метод возвращает код 200 с телом ответа JSON. Результаты
item
приводят к ответуHTTP 200
.
Метод PutTodoItem
Изучите метод PutTodoItem
:
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
if (id != todoItem.Id)
{
return BadRequest();
}
_context.Entry(todoItem).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
PutTodoItem
аналогичен PostTodoItem
, за исключением того, что он использует HTTP PUT
. Ответ — 204 (Нет содержимого). Согласно спецификации HTTP, PUT
запрос требует от клиента отправки всей обновленной сущности, а не только изменений. To support partial updates, use HTTP PATCH.
Тестирование метода PutTodoItem
В этом примере используется база данных в памяти, которая должна быть инициирована при каждом запуске приложения. При выполнении вызова PUT в базе данных уже должен существовать какой-либо элемент. Для этого перед вызовом PUT выполните вызов GET, чтобы убедиться в наличии такого элемента в базе данных.
Используя Swagger UI, нажмите кнопку PUT, чтобы обновить TodoItem
с идентификатором 1 и установить его имя как "feed fish"
. Обратите внимание, что ответ равен HTTP 204 No Content
.
Метод DeleteTodoItem
Изучите метод DeleteTodoItem
:
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
Тестирование метода DeleteTodoItem
Используйте интерфейс Swagger для удаления TodoItem
, у которого идентификатор = 1. Обратите внимание, что ответ равен HTTP 204 No Content
.
Тестирование с помощью других средств
Существует множество других средств, которые можно использовать для тестирования веб-API, например:
- Обозреватель конечных точек Visual Studio и HTTP-файлы
- http-repl
-
curl. Swagger использует
curl
и показывает командыcurl
, которые он отправляет. - Fiddler
Дополнительные сведения см. в разделе:
Prevent over-posting
В настоящее время пример приложения предоставляет весь объект TodoItem
. Рабочие приложения обычно ограничивают вводимые данные и возвращают их с помощью подмножества модели. Такое поведение реализовано по нескольким причинам, но в основном из соображений безопасности. Подмножество модели обычно называется объектом передачи данных (DTO), моделью ввода или моделью представления.
DTO is used in this tutorial.
DTO можно использовать для следующего:
- Prevent over-posting.
- Скрытие свойств, которые не предназначены для просмотра клиентами.
- Пропуск некоторых свойств, чтобы уменьшить размер полезной нагрузки.
- Уплощение графов объектов, которые содержат вложенные объекты. Сведенные графы объектов могут быть удобнее для клиентов.
Чтобы продемонстрировать подход с применением DTO, обновите класс TodoItem
, включив в него поле секрета:
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
}
Поле секрета должно быть скрыто в этом приложении, однако административное приложение может отобразить его.
Убедитесь, что вы можете отправить и получить секретное поле.
Создайте модель DTO:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Обновите TodoItemsController
, так чтобы использовать TodoItemDTO
:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
namespace TodoApi.Controllers;
[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
{
private readonly TodoContext _context;
public TodoItemsController(TodoContext context)
{
_context = context;
}
// GET: api/TodoItems
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
return await _context.TodoItems
.Select(x => ItemToDTO(x))
.ToListAsync();
}
// GET: api/TodoItems/5
// <snippet_GetByID>
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return ItemToDTO(todoItem);
}
// </snippet_GetByID>
// PUT: api/TodoItems/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Update>
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
{
if (id != todoDTO.Id)
{
return BadRequest();
}
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
todoItem.Name = todoDTO.Name;
todoItem.IsComplete = todoDTO.IsComplete;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
return NoContent();
}
// </snippet_Update>
// POST: api/TodoItems
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Create>
[HttpPost]
public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
{
var todoItem = new TodoItem
{
IsComplete = todoDTO.IsComplete,
Name = todoDTO.Name
};
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
return CreatedAtAction(
nameof(GetTodoItem),
new { id = todoItem.Id },
ItemToDTO(todoItem));
}
// </snippet_Create>
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
private bool TodoItemExists(long id)
{
return _context.TodoItems.Any(e => e.Id == id);
}
private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
new TodoItemDTO
{
Id = todoItem.Id,
Name = todoItem.Name,
IsComplete = todoItem.IsComplete
};
}
Убедитесь, что вы не можете отправить или получить секретное поле.
Вызов веб-API с помощью JavaScript
См. руководство: Вызов веб-API ASP.NET Core с помощью JavaScript.
Серия видеороликов по веб-API
Смотрите Видео: Серия для начинающих: Web API.
Шаблоны корпоративных веб-приложений
Рекомендации по созданию надежного, безопасного, производительного, тестового и масштабируемого приложения ASP.NET Core см. в шаблонах веб-приложений Enterprise. Полный пример веб-приложения с высоким качеством рабочей среды, реализующий шаблоны, доступен.
Добавление поддержки аутентификации в веб-API
ASP.NET Core Identity позволяет использовать функцию входа в пользовательском интерфейсе для веб-приложений ASP.NET Core. Чтобы защитить веб-API и SPA, используйте один из следующих способов:
Duende Identity Server — это платформа OpenID Connect и OAuth 2.0 для ASP.NET Core. Duende Identity Server включает следующие функции безопасности:
- Проверка подлинности как услуга (AaaS)
- Единый вход и выход (SSO) для различных типов приложений
- Контроль доступа для API
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Дополнительные сведения см. в статье "Миграция из ASP.NET Core в .NET 5 в .NET 6".
Дополнительные сведения см. в документации по Duende Identity Server (на веб-сайте ПО Duende).
Публикация в Azure
Сведения о развертывании в Azure см. в разделе Краткое руководство. Развертывание веб-приложения ASP.NET.
Additional resources
Просмотреть или скачать пример кода для этого учебника. См. раздел Практическое руководство. Скачивание файла.
Дополнительные сведения см. на следующих ресурсах:
- Создание веб-API с помощью ASP.NET Core
- Руководство. Создание минимального API с помощью ASP.NET Core
- документация по веб-API ASP.NET Core с помощью Swagger / OpenAPI
- Razor
- Маршрутизация на действия контроллера в ASP.NET Core
- Типы возвращаемых действий контроллера в веб-API ASP.NET Core
- Развертывание приложений ASP.NET Core в Службе приложений Azure
- Размещение и развертывание ASP.NET Core
- Создание веб-API с помощью ASP.NET Core
В этом руководстве описаны основы создания веб-API на основе контроллера, использующего базу данных. Another approach to creating APIs in ASP.NET Core is to create minimal APIs. For help with choosing between minimal APIs and controller-based APIs, see APIs overview. См. Руководство: Создание минимального API с помощью ASP.NET Core для получения инструкции по созданию минимального API.
Overview
В этом руководстве создается следующий API-интерфейс:
API | Description | Request body | Response body |
---|---|---|---|
GET /api/todoitems |
Получение всех элементов задач | None | Массив задач |
GET /api/todoitems/{id} |
Получение элемента по идентификатору | None | To-do item |
POST /api/todoitems |
Добавление нового элемента | To-do item | To-do item |
PUT /api/todoitems/{id} |
Обновление существующего элемента | To-do item | None |
DELETE /api/todoitems/{id} |
Удаление элемента | None | None |
На следующем рисунке показана структура приложения.
Prerequisites
Visual Studio 2022 с рабочей нагрузкой ASP.NET и веб-разработка.
Создание веб-проекта
- From the File menu, select New>Project.
- Enter Web API in the search box.
- Выберите шаблон Веб-API ASP.NET Core и нажмите кнопку Далее.
- В диалоговом окне Настроить новый проект присвойте проекту имя TodoApi и нажмите кнопку Далее.
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- Убедитесь, что флажок Use controllers (uncheck to use minimal APIs) (Использовать контроллеры (снимите этот флажок для использования минимальных API)) установлен.
- Убедитесь, что установлен флажок для включения поддержки OpenAPI.
- Select Create.
Добавление пакета NuGet
Пакет NuGet необходимо добавить для поддержки базы данных, используемой в этом руководстве.
- From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for Solution.
- Select the Browse tab.
- Enter Microsoft.EntityFrameworkCore.InMemory in the search box, and then select
Microsoft.EntityFrameworkCore.InMemory
. - Select the Project checkbox in the right pane and then select Install.
Note
Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Confirm correct package versions at NuGet.org.
Тестирование проекта
The project template creates a WeatherForecast
API with support for Swagger.
Нажмите клавиши CTRL+F5, чтобы выполнить запуск без отладчика.
Visual Studio отображает следующее диалоговое окно, если проект еще не настроен для использования SSL:
Select Yes if you trust the IIS Express SSL certificate.
Отобразится следующее диалоговое окно.
Select Yes if you agree to trust the development certificate.
Сведения о доверии к браузеру Firefox см. в разделе Ошибка сертификата браузера Firefox SEC_ERROR_INADEQUATE_KEY_USAGE.
Visual Studio запускает браузер по умолчанию и переходит по адресу https://localhost:<port>/swagger/index.html
, где <port>
— случайно выбранный номер порта при создании проекта.
Откроется страница Swagger /swagger/index.html
. Select GET>Try it out>Execute. На странице отобразятся:
- The Curl command to test the WeatherForecast API.
- URL-адрес для тестирования API WeatherForecast;
- код, текст и заголовки ответа;
- Раскрывающийся список с типами носителей, а также пример значений и схемы.
Если страница Swagger не отображается, см. эту проблему на сайте GitHub.
Swagger используется для создания полезной документации и страниц справки для веб-API. В этом руководстве используется Swagger для тестирования приложения. Дополнительные сведения о Swagger см. в статье Документация по веб-API ASP.NET Core с использованием Swagger (OpenAPI).
Copy and paste the Request URL in the browser: https://localhost:<port>/weatherforecast
Возвращаемые данные JSON будут примерно такими:
[
{
"date": "2019-07-16T19:04:05.7257911-06:00",
"temperatureC": 52,
"temperatureF": 125,
"summary": "Mild"
},
{
"date": "2019-07-17T19:04:05.7258461-06:00",
"temperatureC": 36,
"temperatureF": 96,
"summary": "Warm"
},
{
"date": "2019-07-18T19:04:05.7258467-06:00",
"temperatureC": 39,
"temperatureF": 102,
"summary": "Cool"
},
{
"date": "2019-07-19T19:04:05.7258471-06:00",
"temperatureC": 10,
"temperatureF": 49,
"summary": "Bracing"
},
{
"date": "2019-07-20T19:04:05.7258474-06:00",
"temperatureC": -1,
"temperatureF": 31,
"summary": "Chilly"
}
]
Добавление класса модели
A model is a set of classes that represent the data that the app manages. Для этого приложения используется класс модели TodoItem
.
- In Solution Explorer, right-click the project. Select Add>New Folder. Назовите папку
Models
. - Right-click the
Models
folder and select Add>Class. Name the class TodoItem and select Add. - Замените код шаблона следующим кодом:
namespace TodoApi.Models;
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Свойство Id
выступает в качестве уникального ключа реляционной базы данных.
Классы моделей можно размещать в любом месте проекта, но обычно для этого используется папка Models
.
Добавление контекста базы данных
The database context is the main class that coordinates Entity Framework functionality for a data model. Этот класс является производным от класса Microsoft.EntityFrameworkCore.DbContext.
- Right-click the
Models
folder and select Add>Class. Name the class TodoContext and click Add.
Введите следующий код:
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models; public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } = null!; }
Регистрация контекста базы данных
В ASP.NET Core службы (такие как контекст базы данных) должны быть зарегистрированы с помощью контейнера внедрения зависимостей. Контейнер предоставляет службу контроллерам.
Обновите Program.cs
, используя выделенный код:
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Предыдущий код:
- Добавляет
using
директивы. - Добавляет контекст базы данных в контейнер внедрения зависимостей.
- Указывает, что контекст базы данных будет использовать базу данных в памяти.
Создание каркаса контроллера
Щелкните правой кнопкой мыши папку
Controllers
.Select Add>New Scaffolded Item.
Выберите Контроллер API с действиями, использующий Entity Framework, а затем выберите Добавить.
В диалоговом окне Добавить контроллер API с действиями, используя Entity Framework:
- Select TodoItem (TodoApi.Models) in the Model class.
- Select TodoContext (TodoApi.Models) in the Data context class.
- Select Add.
If the scaffolding operation fails, select Add to try scaffolding a second time.
Сформированный код:
- Пометьте этот класс атрибутом
[ApiController]
. Этот атрибут указывает, что контроллер отвечает на запросы веб-API. Дополнительные сведения о поведении, которое реализует этот атрибут, см. в статье Создание веб-API с помощью ASP.NET Core. - Использует DI для инъекции контекста базы данных (
TodoContext
) в контроллер. The database context is used in each of the CRUD methods in the controller.
Шаблоны ASP.NET Core для:
- Контроллеры с представлениями включают
[action]
в шаблоне маршрута. - Контроллеры API не включают
[action]
в шаблоне маршрута.
When the [action]
token isn't in the route template, the action name (method name) isn't included in the endpoint. То есть имя связанного метода действия не используется в соответствующем маршруте.
Обновление метода создания PostTodoItem
Update the return statement in the PostTodoItem
to use the nameof operator:
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
// return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}
Предыдущий код является методом HTTP POST
, как указано атрибутом [HttpPost]
. Метод получает значение TodoItem
из текста HTTP-запроса.
Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
Метод CreatedAtAction:
- В случае успеха возвращает код состояния HTTP 201.
HTTP 201
— это стандартныйHTTP POST
ответ для метода, создающего новый ресурс на сервере. - Adds a Location header to the response. The
Location
header specifies the URI of the newly created to-do item. Дополнительные сведения см. в разделе 10.2.2 201 «Создан ресурс». - Указывает действие
GetTodoItem
для создания URI заголовкаLocation
. Ключевое словоnameof
C# используется для предотвращения жесткого программирования имени действия в вызовеCreatedAtAction
.
Test PostTodoItem
Нажмите клавиши CTRL+F5, чтобы запустить приложение.
In the Swagger browser window, select POST /api/TodoItems, and then select Try it out.
In the Request body input window, update the JSON. For example,
{ "name": "walk dog", "isComplete": true }
Select Execute
Тестирование URI заголовка поля 'Location'
In the preceding POST, the Swagger UI shows the location header under Response headers. Например, location: https://localhost:7260/api/TodoItems/1
. Заголовок расположения отображает универсальный код ресурса (URI) для созданного ресурса.
Чтобы проверить заголовок расположения, выполните следующие действия.
In the Swagger browser window, select GET /api/TodoItems/{id}, and then select Try it out.
Enter
1
in theid
input box, and then select Execute.
Знакомство с методами GET
Реализуются две конечные точки GET:
GET /api/todoitems
GET /api/todoitems/{id}
В предыдущем разделе показан пример /api/todoitems/{id}
маршрута.
Follow the POST instructions to add another todo item, and then test the /api/todoitems
route using Swagger.
Это приложение использует базу данных в оперативной памяти. Если приложение остановлено и запущено, предыдущий запрос GET не возвращает никаких данных. If no data is returned, POST data to the app.
Маршрутизация и пути URL
Атрибут [HttpGet]
обозначает метод, который отвечает на HTTP GET
запрос. Путь URL для каждого метода формируется следующим образом:
Начните с строки шаблона в атрибуте
Route
контроллера.[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase
Замените
[controller]
именем контроллера (по соглашению это имя класса контроллера без суффикса "Controller"). For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.Если атрибут
[HttpGet]
имеет шаблон маршрута (например,[HttpGet("products")]
), добавьте его к пути. В этом примере шаблон не используется. Дополнительные сведения см. в разделе Маршрутизация атрибутов с помощью атрибутов Http[Verb].
В следующем методе GetTodoItem
"{id}"
— это переменная-заполнитель для уникального идентификатора элемента задачи. При вызове GetTodoItem
, значение "{id}"
из URL-адреса передаётся методу через параметр id
.
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Return values
Тип возвращаемого значения для методов GetTodoItems
и GetTodoItem
— ActionResult<T>. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200 OK, assuming there are no unhandled exceptions. Необработанные исключения преобразуются в ошибки 5xx.
Типы возвращаемых значений ActionResult
могут представлять широкий спектр кодов состояний HTTP. Например, метод GetTodoItem
может возвращать два разных значения состояния:
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- В противном случае метод возвращает код 200 с телом ответа JSON. Результаты
item
приводят к ответуHTTP 200
.
Метод PutTodoItem
Изучите метод PutTodoItem
:
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
if (id != todoItem.Id)
{
return BadRequest();
}
_context.Entry(todoItem).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
PutTodoItem
аналогичен PostTodoItem
, за исключением того, что он использует HTTP PUT
. Ответ — 204 (Нет содержимого). Согласно спецификации HTTP, PUT
запрос требует от клиента отправки всей обновленной сущности, а не только изменений. To support partial updates, use HTTP PATCH.
Тестирование метода PutTodoItem
В этом примере используется база данных в памяти, которая должна быть инициирована при каждом запуске приложения. При выполнении вызова PUT в базе данных уже должен существовать какой-либо элемент. Для этого перед вызовом PUT выполните вызов GET, чтобы убедиться в наличии такого элемента в базе данных.
Используя Swagger UI, нажмите кнопку PUT, чтобы обновить TodoItem
с идентификатором 1 и установить его имя как "feed fish"
. Обратите внимание, что ответ равен HTTP 204 No Content
.
Метод DeleteTodoItem
Изучите метод DeleteTodoItem
:
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
Тестирование метода DeleteTodoItem
Используйте интерфейс Swagger для удаления TodoItem
, у которого идентификатор = 1. Обратите внимание, что ответ равен HTTP 204 No Content
.
Тестирование с помощью других средств
Существует множество других средств, которые можно использовать для тестирования веб-API, например:
- Обозреватель конечных точек Visual Studio и HTTP-файлы
- http-repl
-
curl. Swagger использует
curl
и показывает командыcurl
, которые он отправляет. - Fiddler
Дополнительные сведения см. в разделе:
Prevent over-posting
В настоящее время пример приложения предоставляет весь объект TodoItem
. Рабочие приложения обычно ограничивают вводимые данные и возвращают их с помощью подмножества модели. Такое поведение реализовано по нескольким причинам, но в основном из соображений безопасности. Подмножество модели обычно называется объектом передачи данных (DTO), моделью ввода или моделью представления.
DTO is used in this tutorial.
DTO можно использовать для следующего:
- Prevent over-posting.
- Скрытие свойств, которые не предназначены для просмотра клиентами.
- Пропуск некоторых свойств, чтобы уменьшить размер полезной нагрузки.
- Уплощение графов объектов, которые содержат вложенные объекты. Сведенные графы объектов могут быть удобнее для клиентов.
Чтобы продемонстрировать подход с применением DTO, обновите класс TodoItem
, включив в него поле секрета:
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
public string? Secret { get; set; }
}
}
Поле секрета должно быть скрыто в этом приложении, однако административное приложение может отобразить его.
Убедитесь, что вы можете отправить и получить секретное поле.
Создайте модель DTO:
namespace TodoApi.Models;
public class TodoItemDTO
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
Обновите TodoItemsController
, так чтобы использовать TodoItemDTO
:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
namespace TodoApi.Controllers;
[Route("api/[controller]")]
[ApiController]
public class TodoItemsController : ControllerBase
{
private readonly TodoContext _context;
public TodoItemsController(TodoContext context)
{
_context = context;
}
// GET: api/TodoItems
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
return await _context.TodoItems
.Select(x => ItemToDTO(x))
.ToListAsync();
}
// GET: api/TodoItems/5
// <snippet_GetByID>
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return ItemToDTO(todoItem);
}
// </snippet_GetByID>
// PUT: api/TodoItems/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Update>
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItemDTO todoDTO)
{
if (id != todoDTO.Id)
{
return BadRequest();
}
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
todoItem.Name = todoDTO.Name;
todoItem.IsComplete = todoDTO.IsComplete;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
return NoContent();
}
// </snippet_Update>
// POST: api/TodoItems
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
// <snippet_Create>
[HttpPost]
public async Task<ActionResult<TodoItemDTO>> PostTodoItem(TodoItemDTO todoDTO)
{
var todoItem = new TodoItem
{
IsComplete = todoDTO.IsComplete,
Name = todoDTO.Name
};
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
return CreatedAtAction(
nameof(GetTodoItem),
new { id = todoItem.Id },
ItemToDTO(todoItem));
}
// </snippet_Create>
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
private bool TodoItemExists(long id)
{
return _context.TodoItems.Any(e => e.Id == id);
}
private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
new TodoItemDTO
{
Id = todoItem.Id,
Name = todoItem.Name,
IsComplete = todoItem.IsComplete
};
}
Убедитесь, что вы не можете отправить или получить секретное поле.
Вызов веб-API с помощью JavaScript
См. руководство: Вызов веб-API ASP.NET Core с помощью JavaScript.
Серия видеороликов по веб-API
Смотрите Видео: Серия для начинающих: Web API.
Шаблоны корпоративных веб-приложений
Рекомендации по созданию надежного, безопасного, производительного, тестового и масштабируемого приложения ASP.NET Core см. в шаблонах веб-приложений Enterprise. Полный пример веб-приложения с высоким качеством рабочей среды, реализующий шаблоны, доступен.
Добавление поддержки аутентификации в веб-API
ASP.NET Core Identity позволяет использовать функцию входа в пользовательском интерфейсе для веб-приложений ASP.NET Core. Чтобы защитить веб-API и SPA, используйте один из следующих способов:
Duende Identity Server — это платформа OpenID Connect и OAuth 2.0 для ASP.NET Core. Duende Identity Server включает следующие функции безопасности:
- Проверка подлинности как услуга (AaaS)
- Единый вход и выход (SSO) для различных типов приложений
- Контроль доступа для API
- Federation Gateway
Important
Duende Software might require you to pay a license fee for production use of Duende Identity Server. Дополнительные сведения см. в статье "Миграция из ASP.NET Core в .NET 5 в .NET 6".
Дополнительные сведения см. в документации по Duende Identity Server (на веб-сайте ПО Duende).
Публикация в Azure
Сведения о развертывании в Azure см. в разделе Краткое руководство. Развертывание веб-приложения ASP.NET.
Additional resources
Просмотреть или скачать пример кода для этого учебника. См. раздел Практическое руководство. Скачивание файла.
Дополнительные сведения см. на следующих ресурсах:
- Создание веб-API с помощью ASP.NET Core
- Руководство. Создание минимального API с помощью ASP.NET Core
- документация по веб-API ASP.NET Core с помощью Swagger / OpenAPI
- Razor
- Маршрутизация на действия контроллера в ASP.NET Core
- Типы возвращаемых действий контроллера в веб-API ASP.NET Core
- Развертывание приложений ASP.NET Core в Службе приложений Azure
- Размещение и развертывание ASP.NET Core
- Создание веб-API с помощью ASP.NET Core
ASP.NET Core