Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。
Warning
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。
Important
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。
By Tim Deschryver and Rick Anderson
このチュートリアルでは、データベースを使用するコントローラー ベースの Web 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 |
すべての To Do アイテムを取得します。 | None | To Do アイテムの配列 |
GET /api/todoitems/{id} |
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
ASP.NET および Web 開発ワークロードを含む Visual Studio 2022。
Web API プロジェクトを作成する
- From the File menu, select New>Project.
- Enter Web API in the search box.
- ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
- [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に 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 ドキュメント)」の記事を参照してください。 Confirm correct package versions at NuGet.org.
プロジェクトを実行する
The project template creates a WeatherForecast
API with support for OpenAPI.
Ctrl + F5 キーを押して、デバッガーなしで実行します。
SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。
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 を返します。
URL に /weatherforecast
を追加して WeatherForecast API をテストします。
ブラウザーには、次の例のような 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"
}
]
プロジェクトをテストする
このチュートリアルでは 、エンドポイント エクスプローラーと .http ファイル を使用して API をテストします。
モデル クラスの追加
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 では、DB コンテキストなどのサービスを 依存関係挿入 (DI) コンテナーに登録する必要があります。 コンテナーは、コントローラーにサービスを提供します。
次の強調表示されているコードを使用して、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
ディレクティブを追加します。 - DI コンテナーにデータベース コンテキストを追加します。
- データベース コンテキストがメモリ内データベースを使用することを指定します。
コントローラーのスキャフォールディング
Controllers
フォルダーを右クリックしします。Select Add>New Scaffolded Item.
Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。
[Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。
- 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]
属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。 - 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]
メソッドです。 このメソッドは、HTTP 要求の本文から TodoItem
の値を取得します。
詳細については、「 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 Created」を参照してください。 -
GetTodoItem
アクションを参照してLocation
ヘッダーの URI を作成します。 C# のnameof
キーワードを使って、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
が必要です。 todo を定義するには、//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 のテスト
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 メソッドの確認
2 つの 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}"
は To Do アイテムの一意識別子に使用するプレースホルダーの変数です。
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
は、次の 2 つの異なる状態値を返す可能性があります。
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- それ以外の場合、メソッドは JSON 応答本文で 200 を返します。 戻り値が
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 呼び出しを実行する前に、データベース内にアイテムが存在している必要があります。 GET を呼び出して、PUT 呼び出しを実行する前にデータベース内にアイテムが確実に存在していることを確認します。
id = 1 のPUT
を更新し、その名前を TodoItem
に設定するには、"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 メソッドのテスト
id = 1 のDELETE
を削除するには、TodoItem
メソッドを使用します。 応答は HTTP 204 No Content
であることに注意してください。
In Endpoints Explorer, right-click the DELETE endpoint and select Generate request.
DELETE 要求が
TodoApi.http
に追加されます。DELETE 要求行の
{{id}}
を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 です。
他のツールでテストする
Web 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
};
}
シークレット フィールドを投稿または取得できないことを確認します。
JavaScript を使用した Web API の呼び出し
「 チュートリアル: JavaScript を使用して ASP.NET Core Web API を呼び出す」を参照してください。
Web API ビデオ シリーズ
ビデオ: 初心者向けシリーズ:Web API を参照してください。
エンタープライズ Web アプリのパターン
信頼性が高く、セキュリティで保護され、パフォーマンスが高く、テスト可能でスケーラブルな ASP.NET Core アプリの作成に関するガイダンスについては、 エンタープライズ Web アプリのパターンに関するページを参照してください。 パターンを実装する完全な運用品質のサンプル Web アプリを使用できます。
Web API に認証サポートを追加
ASP.NET Core Identity では、ASP.NET Core Web アプリにユーザー インターフェイス (UI) ログイン機能が追加されます。 Web API と SPA をセキュリティで保護するには、次のいずれかを使用します。
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 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. 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。
詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。
Azure に発行する
Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。
Additional resources
このチュートリアルのサンプル コードを表示またはダウンロードします。 ダウンロードする方法を参照してください。
詳細については、次のリソースを参照してください。
- ASP.NET Core を使用して Web API を作成する
- チュートリアル: ASP.NET Core を使用して最小限の API を作成する
- 生成された OpenAPI ドキュメントを使用する
- Swagger/OpenAPI を使用した ASP.NET Core Web API ドキュメント
- Razor ASP.NET Core の Entity Framework Core を含むページ - チュートリアル 1/8
- ASP.NET Core でのコントローラー アクションへのルーティング
- ASP.NET Core Web API のコントローラー アクションの戻り値の型
- ASP.NET Core アプリを Azure App Service にデプロイする
- ASP.NET Core のホストとデプロイ
- ASP.NET Core を使用して Web API を作成する
このチュートリアルでは、データベースを使用するコントローラー ベースの Web 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 |
すべての To Do アイテムを取得します。 | None | To Do アイテムの配列 |
GET /api/todoitems/{id} |
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
ASP.NET および Web 開発ワークロードを含む Visual Studio 2022。
Web プロジェクトの作成
- From the File menu, select New>Project.
- Enter Web API in the search box.
- ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
- [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に TodoApi という名前を付け、[ 次へ] を選択します。
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- [コントローラーを使用する( 最小限の 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 ドキュメント)」の記事を参照してください。 Confirm correct package versions at NuGet.org.
プロジェクトをテストする
The project template creates a WeatherForecast
API with support for Swagger.
Ctrl + F5 キーを押して、デバッガーなしで実行します。
SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。
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.
- WeatherForecast API をテストする URL。
- 応答コード、本文、およびヘッダー。
- メディアの種類と、値とスキーマの例を含むドロップダウン リスト ボックス。
Swagger ページが表示されない場合は、 この GitHub の問題を参照してください。
Swagger は、Web API の有用なドキュメントやヘルプ ページを生成するために使用されます。 このチュートリアルでは、Swagger を使ってアプリをテストします。 Swagger の詳細については、Swagger /OpenAPI ASP.NET Core Web API のドキュメントを参照してください。
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 では、DB コンテキストなどのサービスを 依存関係挿入 (DI) コンテナーに登録する必要があります。 コンテナーは、コントローラーにサービスを提供します。
次の強調表示されているコードを使用して、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
ディレクティブを追加します。 - DI コンテナーにデータベース コンテキストを追加します。
- データベース コンテキストがメモリ内データベースを使用することを指定します。
コントローラーのスキャフォールディング
Controllers
フォルダーを右クリックしします。Select Add>New Scaffolded Item.
Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。
[Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。
- 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]
属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。 - 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]
メソッドです。 このメソッドは、HTTP 要求の本文から TodoItem
の値を取得します。
詳細については、「 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 Created」を参照してください。 -
GetTodoItem
アクションを参照してLocation
ヘッダーの URI を作成します。 C# のnameof
キーワードを使って、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 のテスト
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 メソッドの確認
2 つの 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}"
は To Do アイテムの一意識別子に使用するプレースホルダーの変数です。
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
は、次の 2 つの異なる状態値を返す可能性があります。
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- それ以外の場合、メソッドは JSON 応答本文で 200 を返します。 戻り値が
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 呼び出しを実行する前に、データベース内にアイテムが存在している必要があります。 GET を呼び出して、PUT 呼び出しを実行する前にデータベース内にアイテムが確実に存在していることを確認します。
Swagger UI を使用して、PUT ボタンを使用して Id = 1 の TodoItem
を更新し、その名前を "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 UI を使用して、Id = 1 の TodoItem
を削除します。 応答は HTTP 204 No Content
であることに注意してください。
他のツールでテストする
Web 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
};
}
シークレット フィールドを投稿または取得できないことを確認します。
JavaScript を使用した Web API の呼び出し
「 チュートリアル: JavaScript を使用して ASP.NET Core Web API を呼び出す」を参照してください。
Web API ビデオ シリーズ
ビデオ: 初心者向けシリーズ:Web API を参照してください。
エンタープライズ Web アプリのパターン
信頼性が高く、セキュリティで保護され、パフォーマンスが高く、テスト可能でスケーラブルな ASP.NET Core アプリの作成に関するガイダンスについては、 エンタープライズ Web アプリのパターンに関するページを参照してください。 パターンを実装する完全な運用品質のサンプル Web アプリを使用できます。
Web API に認証サポートを追加
ASP.NET Core Identity では、ASP.NET Core Web アプリにユーザー インターフェイス (UI) ログイン機能が追加されます。 Web API と SPA をセキュリティで保護するには、次のいずれかを使用します。
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 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. 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。
詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。
Azure に発行する
Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。
Additional resources
このチュートリアルのサンプル コードを表示またはダウンロードします。 ダウンロードする方法を参照してください。
詳細については、次のリソースを参照してください。
- ASP.NET Core を使用して Web API を作成する
- チュートリアル: ASP.NET Core を使用して最小限の API を作成する
- Swagger/OpenAPI を使用した ASP.NET Core Web API ドキュメント
- Razor ASP.NET Core の Entity Framework Core を含むページ - チュートリアル 1/8
- ASP.NET Core でのコントローラー アクションへのルーティング
- ASP.NET Core Web API のコントローラー アクションの戻り値の型
- ASP.NET Core アプリを Azure App Service にデプロイする
- ASP.NET Core のホストとデプロイ
- ASP.NET Core を使用して Web API を作成する
このチュートリアルでは、データベースを使用するコントローラー ベースの Web 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 |
すべての To Do アイテムを取得します。 | None | To Do アイテムの配列 |
GET /api/todoitems/{id} |
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
ASP.NET および Web 開発ワークロードを含む Visual Studio 2022。
Web プロジェクトの作成
- From the File menu, select New>Project.
- Enter Web API in the search box.
- ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
- [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に TodoApi という名前を付け、[ 次へ] を選択します。
- In the Additional information dialog:
- Confirm the Framework is .NET 8.0 (Long Term Support).
- [コントローラーを使用する( 最小限の 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 ドキュメント)」の記事を参照してください。 Confirm correct package versions at NuGet.org.
プロジェクトをテストする
The project template creates a WeatherForecast
API with support for Swagger.
Ctrl + F5 キーを押して、デバッガーなしで実行します。
SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。
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.
- WeatherForecast API をテストする URL。
- 応答コード、本文、およびヘッダー。
- メディアの種類と、値とスキーマの例を含むドロップダウン リスト ボックス。
Swagger ページが表示されない場合は、 この GitHub の問題を参照してください。
Swagger は、Web API の有用なドキュメントやヘルプ ページを生成するために使用されます。 このチュートリアルでは、Swagger を使ってアプリをテストします。 Swagger の詳細については、Swagger /OpenAPI ASP.NET Core Web API のドキュメントを参照してください。
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 では、DB コンテキストなどのサービスを 依存関係挿入 (DI) コンテナーに登録する必要があります。 コンテナーは、コントローラーにサービスを提供します。
次の強調表示されているコードを使用して、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
ディレクティブを追加します。 - DI コンテナーにデータベース コンテキストを追加します。
- データベース コンテキストがメモリ内データベースを使用することを指定します。
コントローラーのスキャフォールディング
Controllers
フォルダーを右クリックしします。Select Add>New Scaffolded Item.
Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。
[Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。
- 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]
属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。 - 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]
メソッドです。 このメソッドは、HTTP 要求の本文から TodoItem
の値を取得します。
詳細については、「 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 Created」を参照してください。 -
GetTodoItem
アクションを参照してLocation
ヘッダーの URI を作成します。 C# のnameof
キーワードを使って、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 のテスト
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 メソッドの確認
2 つの 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}"
は To Do アイテムの一意識別子に使用するプレースホルダーの変数です。
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
は、次の 2 つの異なる状態値を返す可能性があります。
- If no item matches the requested ID, the method returns a 404 statusNotFound error code.
- それ以外の場合、メソッドは JSON 応答本文で 200 を返します。 戻り値が
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 呼び出しを実行する前に、データベース内にアイテムが存在している必要があります。 GET を呼び出して、PUT 呼び出しを実行する前にデータベース内にアイテムが確実に存在していることを確認します。
Swagger UI を使用して、PUT ボタンを使用して Id = 1 の TodoItem
を更新し、その名前を "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 UI を使用して、Id = 1 の TodoItem
を削除します。 応答は HTTP 204 No Content
であることに注意してください。
他のツールでテストする
Web 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
};
}
シークレット フィールドを投稿または取得できないことを確認します。
JavaScript を使用した Web API の呼び出し
「 チュートリアル: JavaScript を使用して ASP.NET Core Web API を呼び出す」を参照してください。
Web API ビデオ シリーズ
ビデオ: 初心者向けシリーズ:Web API を参照してください。
エンタープライズ Web アプリのパターン
信頼性が高く、セキュリティで保護され、パフォーマンスが高く、テスト可能でスケーラブルな ASP.NET Core アプリの作成に関するガイダンスについては、 エンタープライズ Web アプリのパターンに関するページを参照してください。 パターンを実装する完全な運用品質のサンプル Web アプリを使用できます。
Web API に認証サポートを追加
ASP.NET Core Identity では、ASP.NET Core Web アプリにユーザー インターフェイス (UI) ログイン機能が追加されます。 Web API と SPA をセキュリティで保護するには、次のいずれかを使用します。
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 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. 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。
詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。
Azure に発行する
Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。
Additional resources
このチュートリアルのサンプル コードを表示またはダウンロードします。 ダウンロードする方法を参照してください。
詳細については、次のリソースを参照してください。
- ASP.NET Core を使用して Web API を作成する
- チュートリアル: ASP.NET Core を使用して最小限の API を作成する
- Swagger/OpenAPI を使用した ASP.NET Core Web API ドキュメント
- Razor ASP.NET Core の Entity Framework Core を含むページ - チュートリアル 1/8
- ASP.NET Core でのコントローラー アクションへのルーティング
- ASP.NET Core Web API のコントローラー アクションの戻り値の型
- ASP.NET Core アプリを Azure App Service にデプロイする
- ASP.NET Core のホストとデプロイ
- ASP.NET Core を使用して Web API を作成する
ASP.NET Core