次の方法で共有


チュートリアル: ASP.NET Core を使用してコントローラー ベースの Web API を作成する

これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、 この記事の .NET 9 バージョンを参照してください。

Tim DeschryverRick Anderson

このチュートリアルでは、データベースを使用するコントローラー ベースの Web API の構築の基本について説明します。 ASP.NET Core で API を作成するもう 1 つの方法は、"最小 API" を作成することです。 最小限の API とコントローラー ベースの API の選択に関するヘルプについては、 API の概要を参照してください。 最小限の API の作成に関するチュートリアルについては、「 チュートリアル: ASP.NET Core を使用して最小限の API を作成する」を参照してください。

概要

このチュートリアルでは、次の API を作成します。

API(アプリケーション・プログラミング・インターフェース) 説明 要求本文 応答本文
GET /api/todoitems すべての To Do アイテムを取得します。 無し To Do アイテムの配列
GET /api/todoitems/{id} ID でアイテムを取得します。 無し To Do アイテム
POST /api/todoitems 新しいアイテムを追加します。 To Do アイテム To Do アイテム
PUT /api/todoitems/{id} 既存のアイテムを更新します。 To Do アイテム 無し
DELETE /api/todoitems/{id}     アイテムを削除します。 無し 無し

次の図は、アプリのデザインを示しています。

クライアントは左側のボックスで表されます。要求を送信し、アプリケーションからの応答 (右側に描画されたボックス) を受け取ります。アプリケーション ボックス内の 3 つのボックスは、コントローラー、モデル、およびデータ アクセス層を表します。要求はアプリケーションのコントローラーに送信され、コントローラーとデータ アクセス層の間で読み取り/書き込み操作が行われます。モデルがシリアル化され、応答でクライアントに返されます。

前提条件

Web API プロジェクトを作成する

  • [ ファイル ] メニューの [ 新規>プロジェクト] を選択します。
  • 検索ボックスに 「Web API 」と入力します。
  • ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
  • [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に TodoApi という名前を付け、[ 次へ] を選択します。
  • [追加情報] ダイアログで、次の 手順 を実行します。
    • フレームワーク.NET 9.0 (Standard Term Support) であることを確認します。
    • [OpenAPI サポート を有効にする のチェック ボックスがオンになっていることを確認します。
    • [コントローラーを使用する] のチェックボックス (最小限の API を使用するにはオフ) が オンになっていることを確認します。
    • 作成を選択します。

NuGet パッケージの追加

このチュートリアルで使うデータベースをサポートするには、NuGet パッケージを追加する必要があります。

  • [ ツール ] メニューの [ NuGet パッケージ マネージャー] > [ソリューションの NuGet パッケージの管理] を選択します。
  • [参照] タブを選択します。
  • 検索ボックスに 「Microsoft.EntityFrameworkCore.InMemory 」と入力し、 Microsoft.EntityFrameworkCore.InMemoryを選択します。
  • 右側のウィンドウで [ プロジェクト ] チェック ボックスをオンにし、[ インストール] を選択します。

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ消費ワークフローでの パッケージのインストールと管理(NuGet ドキュメント)」の記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

プロジェクトを実行する

プロジェクト テンプレートは、WeatherForecast をサポートする API を作成します。

Ctrl + F5 キーを押して、デバッガーなしで実行します。

SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。

このプロジェクトは、SSL を使用するように構成されています。ブラウザーで SSL 警告を回避するには、IIS Express によって生成された自己署名証明書を信頼することを選択できます。IIS Express SSL 証明書を信頼しますか?

IIS Express SSL 証明書を信頼する場合は、[ はい ] を選択します。

次のダイアログが表示されます。

[セキュリティの警告] ダイアログ

開発証明書を信頼することに同意する場合は、[ はい ] を選択します。

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.
...

+で HTTPS URL をクリックして、ブラウザーで Web アプリをテストします。 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 をテストします。

モデル クラスの追加

モデルは、アプリが管理するデータを表すクラスのセットです。 このアプリのモデルは、TodoItem クラスです。

  • ソリューション エクスプローラー で、プロジェクトを右クリックします。 [ 追加>新しいフォルダー] を選択します。 フォルダーに「 Modelsで行うことができます。
  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラスに TodoItem という名前を付 け、[追加] を選択します。
  • テンプレート コードを次のコードに置き換えます。
namespace TodoApi.Models;

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Id プロパティは、リレーショナル データベース内の一意のキーとして機能します。

モデル クラスはプロジェクト内のどこでも使用できますが、慣例により Models フォルダーが使用されます。

データベース コンテキストの追加

データベース コンテキストは、データ モデルの Entity Framework 機能を調整するメイン クラスです。 このクラスは Microsoft.EntityFrameworkCore.DbContext クラスから派生させて作成します。

  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラス に TodoContext という名前を 付け、[追加] をクリックします。

  • 次のコードを入力します。

    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 フォルダーを右クリックしします。

  • [を選択します。

  • Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。

  • [Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。

    • Model クラスTodoItem (TodoApi.Models) を選択します。
    • データ コンテキスト クラスTodoContext (TodoApi.Models) を選択します。
    • 追加を選択します。

    スキャフォールディング操作が失敗した場合は、[ 追加 ] を選択して、もう一度スキャフォールディングを試みます。

この手順では、プロジェクトに Microsoft.VisualStudio.Web.CodeGeneration.DesignMicrosoft.EntityFrameworkCore.Tools NuGet パッケージを追加します。 これらのパッケージは、スキャフォールディングに必要です。

生成されたコードでは次の操作が行われます。

  • クラスを [ApiController] 属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。
  • DI を使用して、データベース コンテキスト (TodoContext) をコントローラーに挿入します。 データベース コンテキストは、コントローラー内の各 CRUD メソッドで使用されます。

ASP.NET Core テンプレートの対象は次のとおりです。

  • ビューを含むコントローラーには、ルート テンプレートの [action] が含まれます。
  • API コントローラーには、ルート テンプレートの [action] が含まれません。

[action] トークンがルート テンプレートにない場合、アクション名 (メソッド名) はエンドポイントに含まれません。 つまり、アクションの関連付けられたメソッド名は一致するルートでは使用されません。

PostTodoItem 作成メソッドの更新

PostTodoItem 演算子を使用するために、 で return ステートメントを更新します。

[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 メソッドに対する標準の応答です。
  • Location ヘッダーを応答に追加します。 Location ヘッダーは、新しく作成された to-do 項目の URI を指定します。 詳細については、「 10.2.2 201 Created」を参照してください。
  • GetTodoItem アクションを参照して Location ヘッダーの URI を作成します。 C# の nameof キーワードを使って、CreatedAtAction 呼び出しでアクション名をハードコーディングすることを回避しています。

PostTodoItem のテスト

  • 表示>メニューを選択し、その他のウィンドウ>からEndpoints Explorerを選びます。

  • POST エンドポイントを右クリックし、[要求の生成] を選択します。

    エンドポイント エクスプローラーのコンテキスト メニューの [要求の生成] メニュー項目が強調表示されています。

    次の例のような内容の 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
    }
    
    ###
    
  • アプリを実行します。

  • 要求行の上にある POST リンクを選択します。

    実行リンクが強調表示された .http ファイル ウィンドウ。

    POST 要求がアプリに送信され、応答ウィンドウに 応答 が表示されます。

    POST 要求からの応答を含む .http ファイル ウィンドウ。

場所ヘッダー URI のテスト

ブラウザーから GET エンドポイントを呼び出すか、 エンドポイント エクスプローラーを使用して、アプリをテストします。 エンドポイント エクスプローラーの手順を次 に示します

  • エンドポイント エクスプローラーで、最初の GET エンドポイントを右クリックし、[要求の生成] を選択します。

    次の内容が TodoApi.http ファイルに追加されます。

    GET {{TodoApi_HostAddress}}/api/todoitems
    
    ###
    
  • 新しい 要求行の上にある GET リンクを選択します。

    GET 要求がアプリに送信され、応答ウィンドウに 応答 が表示されます。

  • 応答本文は次の JSON のようになります。

    [
      {
        "id": 1,
        "name": "walk dog",
        "isComplete": true
      }
    ]
    
  • エンドポイント エクスプローラーで、/api/todoitems/{id}GET エンドポイントを右クリックし、[要求の生成] を選択します。 次の内容が TodoApi.http ファイルに追加されます。

    @id=0
    GET {{TodoApi_HostAddress}}/api/todoitems/{{id}}
    
    ###
    
  • ({@id}ではなく) 10を割り当てます。

  • 新しい GET 要求行の上にある [要求の送信] リンクを選択します。

    GET 要求がアプリに送信され、応答ウィンドウに 応答 が表示されます。

  • 応答本文は次の JSON のようになります。

    {
      "id": 1,
      "name": "walk dog",
      "isComplete": true
    }
    

GET メソッドの確認

2 つの GET エンドポイントが実装されます。

  • GET /api/todoitems
  • GET /api/todoitems/{id}

前のセクションでは、/api/todoitems/{id} ルートの例を示しました。

POST の指示に従って別の todo 項目を追加し、Swagger を使用して/api/todoitemsルートをテストします。

このアプリではメモリ内データベースが使用されます。 アプリが停止して開始された場合、上記の GET 要求はどのようなデータも返しません。 データが返されない場合は、アプリに データを POST します。

ルーティングと URL パス

[HttpGet] 属性は、HTTP GET 要求に応答するメソッドを表します。 各メソッドの URL パスは次のように構成されます。

  • コントローラーの Route 属性でテンプレート文字列を使用します。

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • [controller] をコントローラーの名前 (慣例では "Controller" サフィックスを除くコントローラー クラス名) に置き換えます。 このサンプルでは、コントローラー クラス名は TodoItemsコントローラーであるため、コントローラー名は "TodoItems" です。 ASP.NET Core ルーティング では大文字と小文字が区別されません。

  • [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;
}

戻り値

GetTodoItemsメソッドと GetTodoItem メソッドの戻り値の型は ActionResult<T> 型です。 ASP.NET Core は、オブジェクトを JSON に自動的にシリアル化し、応答メッセージの本文に JSON を書き込みます。 この戻り値の型の応答コードは 200 OK です。ハンドルされない例外がないと仮定します。 ハンドルされない例外は 5xx エラーに変換されます。

ActionResult 戻り値の型は、幅広い範囲の HTTP 状態コードを表すことができます。 たとえば、GetTodoItem は、次の 2 つの異なる状態値を返す可能性があります。

  • 要求された ID と一致する項目がない場合、メソッドは 404 状態NotFound エラー コードを返します。
  • それ以外の場合、メソッドは 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();
}

PutTodoItemPostTodoItem と似ていますが、HTTP PUT を使用します。 応答は 204 (コンテンツなし) です。 HTTP 仕様に従って、PUT 要求では、変更だけでなく、更新されたエンティティ全体を送信するようクライアントに求めます。 部分的な更新をサポートするには、 HTTP PATCH を使用します。

PutTodoItem メソッドのテスト

このサンプルでは、アプリを起動するたびに開始することが必要なメモリ内データベースが使われています。 PUT 呼び出しを実行する前に、データベース内にアイテムが存在している必要があります。 GET を呼び出して、PUT 呼び出しを実行する前にデータベース内にアイテムが確実に存在していることを確認します。

id = 1 のPUTを更新し、その名前を TodoItem に設定するには、"feed fish" メソッドを使用します。 応答は HTTP 204 No Content であることに注意してください。

  • エンドポイント エクスプローラーでPUT エンドポイントを右クリックし、[要求の生成] を選択します。

    次の内容が 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
    }
    
  • 新しい PUT 要求行の上にある [要求の 送信] リンクを選択します。

    PUT 要求がアプリに送信され、応答ウィンドウに 応答 が表示されます。 応答本文は空であり、状態コードは 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 であることに注意してください。

  • エンドポイント エクスプローラーで、DELETE エンドポイントを右クリックし、[要求の生成] を選択します。

    DELETE 要求が TodoApi.http に追加されます。

  • DELETE 要求行の {{id}}1 に置き換えます。 DELETE 要求は次の例のようになります。

    DELETE {{TodoApi_HostAddress}}/api/todoitems/{{id}}
    
    ###
    
  • DELETE リクエスト用の 要求の送信 リンクを選択します。

    DELETE 要求がアプリに送信され、応答ウィンドウに 応答 が表示されます。 応答本文は空であり、状態コードは 204 です。

他のツールでテストする

Web API のテストには、他にも使用できるツールが多数あります。次に例を示します。

過剰な投稿を防止する

現在、サンプル アプリでは TodoItem オブジェクト全体が公開されています。 通常、運用環境のアプリでは、モデルのサブセットを使用して入力されるデータおよび返されるデータが制限されています。 その背景には複数の理由があり、セキュリティは主なものです。 モデルのサブセットは、通常、データ転送オブジェクト (DTO)、入力モデル、またはビュー モデルと呼ばれます。 このチュートリアルでは DTO を使用します。

DTO は次の目的で使用できます。

  • 過剰な投稿を防止する。
  • クライアントが表示しないことになっているプロパティを非表示にする。
  • ペイロード サイズを減らすために、いくつかのプロパティを省略する。
  • 入れ子になったオブジェクトを含むオブジェクト グラフをフラット化する。 フラット化されたオブジェクト グラフは、クライアントにとってより便利になる可能性があります。

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; }
}

シークレット フィールドは、このアプリでは非表示にする必要がありますが、管理アプリの場合は公開することを選択できます。

シークレット フィールドを投稿および取得できることを確認します。

Models/TodoItemsDTO.cs ファイルに 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 をセキュリティで保護するには、次のいずれかを使用します。

Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 Duende Identity Server により、次のセキュリティ機能が有効になります。

  • サービスとしての認証 (AaaS)
  • 複数のアプリケーションの種類でのシングル サインオン/オフ (SSO)
  • API のアクセス制御
  • フェデレーション ゲートウェイ

重要

Duende ソフトウェアでは、DuendeIdentity Server の運用環境での使用に対するライセンス料金の支払いが必要になる場合があります。 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。

詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。

Azure に発行する

Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。

その他の技術情報

このチュートリアルのサンプル コードを表示またはダウンロードしますダウンロードする方法を参照してください。

詳細については、次のリソースを参照してください。

このチュートリアルでは、データベースを使用するコントローラー ベースの Web API の構築の基本について説明します。 ASP.NET Core で API を作成するもう 1 つの方法は、"最小 API" を作成することです。 最小限の API とコントローラー ベースの API の選択に関するヘルプについては、 API の概要を参照してください。 最小限の API の作成に関するチュートリアルについては、「 チュートリアル: ASP.NET Core を使用して最小限の API を作成する」を参照してください。

概要

このチュートリアルでは、次の API を作成します。

API(アプリケーション・プログラミング・インターフェース) 説明 要求本文 応答本文
GET /api/todoitems すべての To Do アイテムを取得します。 無し To Do アイテムの配列
GET /api/todoitems/{id} ID でアイテムを取得します。 無し To Do アイテム
POST /api/todoitems 新しいアイテムを追加します。 To Do アイテム To Do アイテム
PUT /api/todoitems/{id} 既存のアイテムを更新します。 To Do アイテム 無し
DELETE /api/todoitems/{id}     アイテムを削除します。 無し 無し

次の図は、アプリのデザインを示しています。

クライアントは左側のボックスで表されます。要求を送信し、アプリケーションからの応答 (右側に描画されたボックス) を受け取ります。アプリケーション ボックス内の 3 つのボックスは、コントローラー、モデル、およびデータ アクセス層を表します。要求はアプリケーションのコントローラーに送信され、コントローラーとデータ アクセス層の間で読み取り/書き込み操作が行われます。モデルがシリアル化され、応答でクライアントに返されます。

前提条件

Web プロジェクトの作成

  • [ ファイル ] メニューの [ 新規>プロジェクト] を選択します。
  • 検索ボックスに 「Web API 」と入力します。
  • ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
  • [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に TodoApi という名前を付け、[ 次へ] を選択します。
  • [追加情報] ダイアログで、次の 手順 を実行します。
    • フレームワーク.NET 8.0 (長期サポート) であることを確認します。
    • [コントローラーを使用する( 最小限の API を使用する場合はオフ)] チェックボックスがオンになっていることを確認します。
    • [OpenAPI サポート を有効にする のチェック ボックスがオンになっていることを確認します。
    • 作成を選択します。

NuGet パッケージの追加

このチュートリアルで使うデータベースをサポートするには、NuGet パッケージを追加する必要があります。

  • [ ツール ] メニューの [ NuGet パッケージ マネージャー] > [ソリューションの NuGet パッケージの管理] を選択します。
  • [参照] タブを選択します。
  • 検索ボックスに 「Microsoft.EntityFrameworkCore.InMemory 」と入力し、 Microsoft.EntityFrameworkCore.InMemoryを選択します。
  • 右側のウィンドウで [ プロジェクト ] チェック ボックスをオンにし、[ インストール] を選択します。

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ消費ワークフローでの パッケージのインストールと管理(NuGet ドキュメント)」の記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

プロジェクトをテストする

プロジェクト テンプレートにより、WeatherForecast をサポートする API が作成されます。

Ctrl + F5 キーを押して、デバッガーなしで実行します。

SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。

このプロジェクトは、SSL を使用するように構成されています。ブラウザーで SSL 警告を回避するには、IIS Express によって生成された自己署名証明書を信頼することを選択できます。IIS Express SSL 証明書を信頼しますか?

IIS Express SSL 証明書を信頼する場合は、[ はい ] を選択します。

次のダイアログが表示されます。

[セキュリティの警告] ダイアログ

開発証明書を信頼することに同意する場合は、[ はい ] を選択します。

Firefox ブラウザーを信頼する方法については、 Firefox SEC_ERROR_INADEQUATE_KEY_USAGE証明書エラーに関する記事を参照してください。

Visual Studio で既定のブラウザーが起動し、https://localhost:<port>/swagger/index.html にアクセスします。ここで、<port> は、プロジェクト作成時に設定したランダムに選択されたポート番号になります。

Swagger ページ /swagger/index.html が表示されます。 GET>試してみる>実行 を選択します。 ページに以下が表示されます。

  • WeatherForecast API をテストする Curl コマンド。
  • WeatherForecast API をテストする URL。
  • 応答コード、本文、およびヘッダー。
  • メディアの種類と、値とスキーマの例を含むドロップダウン リスト ボックス。

Swagger ページが表示されない場合は、 この GitHub の問題を参照してください。

Swagger は、Web API の有用なドキュメントやヘルプ ページを生成するために使用されます。 このチュートリアルでは、Swagger を使ってアプリをテストします。 Swagger の詳細については、Swagger /OpenAPI ASP.NET Core Web API のドキュメントを参照してください。

要求 URL をコピーしてブラウザーに貼り付けます。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"
    }
]

モデル クラスの追加

モデルは、アプリが管理するデータを表すクラスのセットです。 このアプリのモデルは、TodoItem クラスです。

  • ソリューション エクスプローラー で、プロジェクトを右クリックします。 [ 追加>新しいフォルダー] を選択します。 フォルダーに「 Modelsで行うことができます。
  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラスに TodoItem という名前を付 け、[追加] を選択します。
  • テンプレート コードを次のコードに置き換えます。
namespace TodoApi.Models;

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Id プロパティは、リレーショナル データベース内の一意のキーとして機能します。

モデル クラスはプロジェクト内のどこでも使用できますが、慣例により Models フォルダーが使用されます。

データベース コンテキストの追加

データベース コンテキストは、データ モデルの Entity Framework 機能を調整するメイン クラスです。 このクラスは Microsoft.EntityFrameworkCore.DbContext クラスから派生させて作成します。

  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラス に TodoContext という名前を 付け、[追加] をクリックします。
  • 次のコードを入力します。

    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 フォルダーを右クリックしします。

  • [を選択します。

  • Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。

  • [Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。

    • Model クラスTodoItem (TodoApi.Models) を選択します。
    • データ コンテキスト クラスTodoContext (TodoApi.Models) を選択します。
    • 追加を選択します。

    スキャフォールディング操作が失敗した場合は、[ 追加 ] を選択して、もう一度スキャフォールディングを試みます。

生成されたコードでは次の操作が行われます。

  • クラスを [ApiController] 属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。
  • DI を使用して、データベース コンテキスト (TodoContext) をコントローラーに挿入します。 データベース コンテキストは、コントローラー内の各 CRUD メソッドで使用されます。

ASP.NET Core テンプレートの対象は次のとおりです。

  • ビューを含むコントローラーには、ルート テンプレートの [action] が含まれます。
  • API コントローラーには、ルート テンプレートの [action] が含まれません。

[action] トークンがルート テンプレートにない場合、アクション名 (メソッド名) はエンドポイントに含まれません。 つまり、アクションの関連付けられたメソッド名は一致するルートでは使用されません。

PostTodoItem 作成メソッドの更新

PostTodoItem 演算子を使用するために、 で return ステートメントを更新します。

[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 メソッドに対する標準の応答です。
  • Location ヘッダーを応答に追加します。 Location ヘッダーは、新しく作成された to-do 項目の URI を指定します。 詳細については、「 10.2.2 201 Created」を参照してください。
  • GetTodoItem アクションを参照して Location ヘッダーの URI を作成します。 C# の nameof キーワードを使って、CreatedAtAction 呼び出しでアクション名をハードコーディングすることを回避しています。

PostTodoItem のテスト

  • Ctrl キーを押しながら F5 キーを押して、アプリを実行します。

  • Swagger ブラウザー ウィンドウで、 POST /api/TodoItems を選択し、[ 試してみる] を選択します。

  • 要求本文の入力ウィンドウで、JSON を更新します。 たとえば、 にします。

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • [ 実行] を選択する

    Swagger POST

場所ヘッダー URI のテスト

前の POST では、Swagger UI は応答ヘッダーの下に 場所ヘッダー を表示 します。 たとえば、「 location: https://localhost:7260/api/TodoItems/1 」のように入力します。 場所ヘッダーには、作成されたリソースへの URI が表示されます。

場所ヘッダーをテストするには:

  • Swagger ブラウザー ウィンドウで、 GET /api/TodoItems/{id} を選択し、[ 試してみる] を選択します。

  • 1入力ボックスに「id」と入力し、[実行] を選択します。

    Swagger GET

GET メソッドの確認

2 つの GET エンドポイントが実装されます。

  • GET /api/todoitems
  • GET /api/todoitems/{id}

前のセクションでは、/api/todoitems/{id} ルートの例を示しました。

POST の指示に従って別の todo 項目を追加し、Swagger を使用して/api/todoitemsルートをテストします。

このアプリではメモリ内データベースが使用されます。 アプリが停止して開始された場合、上記の GET 要求はどのようなデータも返しません。 データが返されない場合は、アプリに データを POST します。

ルーティングと URL パス

[HttpGet] 属性は、HTTP GET 要求に応答するメソッドを表します。 各メソッドの URL パスは次のように構成されます。

  • コントローラーの Route 属性でテンプレート文字列を使用します。

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • [controller] をコントローラーの名前 (慣例では "Controller" サフィックスを除くコントローラー クラス名) に置き換えます。 このサンプルでは、コントローラー クラス名は TodoItemsコントローラーであるため、コントローラー名は "TodoItems" です。 ASP.NET Core ルーティング では大文字と小文字が区別されません。

  • [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;
}

戻り値

GetTodoItemsメソッドと GetTodoItem メソッドの戻り値の型は ActionResult<T> 型です。 ASP.NET Core は、オブジェクトを JSON に自動的にシリアル化し、応答メッセージの本文に JSON を書き込みます。 この戻り値の型の応答コードは 200 OK です。ハンドルされない例外がないと仮定します。 ハンドルされない例外は 5xx エラーに変換されます。

ActionResult 戻り値の型は、幅広い範囲の HTTP 状態コードを表すことができます。 たとえば、GetTodoItem は、次の 2 つの異なる状態値を返す可能性があります。

  • 要求された ID と一致する項目がない場合、メソッドは 404 状態NotFound エラー コードを返します。
  • それ以外の場合、メソッドは 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();
}

PutTodoItemPostTodoItem と似ていますが、HTTP PUT を使用します。 応答は 204 (コンテンツなし) です。 HTTP 仕様に従って、PUT 要求では、変更だけでなく、更新されたエンティティ全体を送信するようクライアントに求めます。 部分的な更新をサポートするには、 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 のテストには、他にも使用できるツールが多数あります。次に例を示します。

詳細については、次を参照してください。

過剰な投稿を防止する

現在、サンプル アプリでは TodoItem オブジェクト全体が公開されています。 通常、運用環境のアプリでは、モデルのサブセットを使用して入力されるデータおよび返されるデータが制限されています。 その背景には複数の理由があり、セキュリティは主なものです。 モデルのサブセットは、通常、データ転送オブジェクト (DTO)、入力モデル、またはビュー モデルと呼ばれます。 このチュートリアルでは DTO を使用します。

DTO は次の目的で使用できます。

  • 過剰な投稿を防止する。
  • クライアントが表示しないことになっているプロパティを非表示にする。
  • ペイロード サイズを減らすために、いくつかのプロパティを省略する。
  • 入れ子になったオブジェクトを含むオブジェクト グラフをフラット化する。 フラット化されたオブジェクト グラフは、クライアントにとってより便利になる可能性があります。

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 をセキュリティで保護するには、次のいずれかを使用します。

Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 Duende Identity Server により、次のセキュリティ機能が有効になります。

  • サービスとしての認証 (AaaS)
  • 複数のアプリケーションの種類でのシングル サインオン/オフ (SSO)
  • API のアクセス制御
  • フェデレーション ゲートウェイ

重要

Duende ソフトウェアでは、DuendeIdentity Server の運用環境での使用に対するライセンス料金の支払いが必要になる場合があります。 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。

詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。

Azure に発行する

Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。

その他の技術情報

このチュートリアルのサンプル コードを表示またはダウンロードしますダウンロードする方法を参照してください。

詳細については、次のリソースを参照してください。

このチュートリアルでは、データベースを使用するコントローラー ベースの Web API の構築の基本について説明します。 ASP.NET Core で API を作成するもう 1 つの方法は、"最小 API" を作成することです。 最小限の API とコントローラー ベースの API の選択に関するヘルプについては、 API の概要を参照してください。 最小限の API の作成に関するチュートリアルについては、「 チュートリアル: ASP.NET Core を使用して最小限の API を作成する」を参照してください。

概要

このチュートリアルでは、次の API を作成します。

API(アプリケーション・プログラミング・インターフェース) 説明 要求本文 応答本文
GET /api/todoitems すべての To Do アイテムを取得します。 無し To Do アイテムの配列
GET /api/todoitems/{id} ID でアイテムを取得します。 無し To Do アイテム
POST /api/todoitems 新しいアイテムを追加します。 To Do アイテム To Do アイテム
PUT /api/todoitems/{id} 既存のアイテムを更新します。 To Do アイテム 無し
DELETE /api/todoitems/{id}     アイテムを削除します。 無し 無し

次の図は、アプリのデザインを示しています。

クライアントは左側のボックスで表されます。要求を送信し、アプリケーションからの応答 (右側に描画されたボックス) を受け取ります。アプリケーション ボックス内の 3 つのボックスは、コントローラー、モデル、およびデータ アクセス層を表します。要求はアプリケーションのコントローラーに送信され、コントローラーとデータ アクセス層の間で読み取り/書き込み操作が行われます。モデルがシリアル化され、応答でクライアントに返されます。

前提条件

Web プロジェクトの作成

  • [ ファイル ] メニューの [ 新規>プロジェクト] を選択します。
  • 検索ボックスに 「Web API 」と入力します。
  • ASP.NET Core Web API テンプレートを選択し、[次へ] を選択します。
  • [ 新しいプロジェクトの構成] ダイアログで、プロジェクト に TodoApi という名前を付け、[ 次へ] を選択します。
  • [追加情報] ダイアログで、次の 手順 を実行します。
    • フレームワーク.NET 8.0 (長期サポート) であることを確認します。
    • [コントローラーを使用する( 最小限の API を使用する場合はオフ)] チェックボックスがオンになっていることを確認します。
    • [OpenAPI サポート を有効にする のチェック ボックスがオンになっていることを確認します。
    • 作成を選択します。

NuGet パッケージの追加

このチュートリアルで使うデータベースをサポートするには、NuGet パッケージを追加する必要があります。

  • [ ツール ] メニューの [ NuGet パッケージ マネージャー] > [ソリューションの NuGet パッケージの管理] を選択します。
  • [参照] タブを選択します。
  • 検索ボックスに 「Microsoft.EntityFrameworkCore.InMemory 」と入力し、 Microsoft.EntityFrameworkCore.InMemoryを選択します。
  • 右側のウィンドウで [ プロジェクト ] チェック ボックスをオンにし、[ インストール] を選択します。

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ消費ワークフローでの パッケージのインストールと管理(NuGet ドキュメント)」の記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

プロジェクトをテストする

プロジェクト テンプレートにより、WeatherForecast をサポートする API が作成されます。

Ctrl + F5 キーを押して、デバッガーなしで実行します。

SSL を使用するようにプロジェクトがまだ構成されていない場合、Visual Studio に次のダイアログが表示されます。

このプロジェクトは、SSL を使用するように構成されています。ブラウザーで SSL 警告を回避するには、IIS Express によって生成された自己署名証明書を信頼することを選択できます。IIS Express SSL 証明書を信頼しますか?

IIS Express SSL 証明書を信頼する場合は、[ はい ] を選択します。

次のダイアログが表示されます。

[セキュリティの警告] ダイアログ

開発証明書を信頼することに同意する場合は、[ はい ] を選択します。

Firefox ブラウザーを信頼する方法については、 Firefox SEC_ERROR_INADEQUATE_KEY_USAGE証明書エラーに関する記事を参照してください。

Visual Studio で既定のブラウザーが起動し、https://localhost:<port>/swagger/index.html にアクセスします。ここで、<port> は、プロジェクト作成時に設定したランダムに選択されたポート番号になります。

Swagger ページ /swagger/index.html が表示されます。 GET>試してみる>実行 を選択します。 ページに以下が表示されます。

  • WeatherForecast API をテストする Curl コマンド。
  • WeatherForecast API をテストする URL。
  • 応答コード、本文、およびヘッダー。
  • メディアの種類と、値とスキーマの例を含むドロップダウン リスト ボックス。

Swagger ページが表示されない場合は、 この GitHub の問題を参照してください。

Swagger は、Web API の有用なドキュメントやヘルプ ページを生成するために使用されます。 このチュートリアルでは、Swagger を使ってアプリをテストします。 Swagger の詳細については、Swagger /OpenAPI ASP.NET Core Web API のドキュメントを参照してください。

要求 URL をコピーしてブラウザーに貼り付けます。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"
    }
]

モデル クラスの追加

モデルは、アプリが管理するデータを表すクラスのセットです。 このアプリのモデルは、TodoItem クラスです。

  • ソリューション エクスプローラー で、プロジェクトを右クリックします。 [ 追加>新しいフォルダー] を選択します。 フォルダーに「 Modelsで行うことができます。
  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラスに TodoItem という名前を付 け、[追加] を選択します。
  • テンプレート コードを次のコードに置き換えます。
namespace TodoApi.Models;

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

Id プロパティは、リレーショナル データベース内の一意のキーとして機能します。

モデル クラスはプロジェクト内のどこでも使用できますが、慣例により Models フォルダーが使用されます。

データベース コンテキストの追加

データベース コンテキストは、データ モデルの Entity Framework 機能を調整するメイン クラスです。 このクラスは Microsoft.EntityFrameworkCore.DbContext クラスから派生させて作成します。

  • Models フォルダーを右クリックし、[追加>Class] を選択します。 クラス に TodoContext という名前を 付け、[追加] をクリックします。
  • 次のコードを入力します。

    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 フォルダーを右クリックしします。

  • [を選択します。

  • Entity Framework を使用して、アクションを含む API コントローラーを選択し、[追加] を選択します。

  • [Entity Framework を使用したアクションを含む API コントローラーの追加] ダイアログで、次の操作を行います。

    • Model クラスTodoItem (TodoApi.Models) を選択します。
    • データ コンテキスト クラスTodoContext (TodoApi.Models) を選択します。
    • 追加を選択します。

    スキャフォールディング操作が失敗した場合は、[ 追加 ] を選択して、もう一度スキャフォールディングを試みます。

生成されたコードでは次の操作が行われます。

  • クラスを [ApiController] 属性でマークします。 この属性は、コントローラーが Web API 要求に応答することを示します。 属性が有効にする特定の動作については、「 ASP.NET Core を使用した Web API の作成」を参照してください。
  • DI を使用して、データベース コンテキスト (TodoContext) をコントローラーに挿入します。 データベース コンテキストは、コントローラー内の各 CRUD メソッドで使用されます。

ASP.NET Core テンプレートの対象は次のとおりです。

  • ビューを含むコントローラーには、ルート テンプレートの [action] が含まれます。
  • API コントローラーには、ルート テンプレートの [action] が含まれません。

[action] トークンがルート テンプレートにない場合、アクション名 (メソッド名) はエンドポイントに含まれません。 つまり、アクションの関連付けられたメソッド名は一致するルートでは使用されません。

PostTodoItem 作成メソッドの更新

PostTodoItem 演算子を使用するために、 で return ステートメントを更新します。

[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 メソッドに対する標準の応答です。
  • Location ヘッダーを応答に追加します。 Location ヘッダーは、新しく作成された to-do 項目の URI を指定します。 詳細については、「 10.2.2 201 Created」を参照してください。
  • GetTodoItem アクションを参照して Location ヘッダーの URI を作成します。 C# の nameof キーワードを使って、CreatedAtAction 呼び出しでアクション名をハードコーディングすることを回避しています。

PostTodoItem のテスト

  • Ctrl キーを押しながら F5 キーを押して、アプリを実行します。

  • Swagger ブラウザー ウィンドウで、 POST /api/TodoItems を選択し、[ 試してみる] を選択します。

  • 要求本文の入力ウィンドウで、JSON を更新します。 たとえば、 にします。

    {
      "name": "walk dog",
      "isComplete": true
    }
    
  • [ 実行] を選択する

    Swagger POST

場所ヘッダー URI のテスト

前の POST では、Swagger UI は応答ヘッダーの下に 場所ヘッダー を表示 します。 たとえば、「 location: https://localhost:7260/api/TodoItems/1 」のように入力します。 場所ヘッダーには、作成されたリソースへの URI が表示されます。

場所ヘッダーをテストするには:

  • Swagger ブラウザー ウィンドウで、 GET /api/TodoItems/{id} を選択し、[ 試してみる] を選択します。

  • 1入力ボックスに「id」と入力し、[実行] を選択します。

    Swagger GET

GET メソッドの確認

2 つの GET エンドポイントが実装されます。

  • GET /api/todoitems
  • GET /api/todoitems/{id}

前のセクションでは、/api/todoitems/{id} ルートの例を示しました。

POST の指示に従って別の todo 項目を追加し、Swagger を使用して/api/todoitemsルートをテストします。

このアプリではメモリ内データベースが使用されます。 アプリが停止して開始された場合、上記の GET 要求はどのようなデータも返しません。 データが返されない場合は、アプリに データを POST します。

ルーティングと URL パス

[HttpGet] 属性は、HTTP GET 要求に応答するメソッドを表します。 各メソッドの URL パスは次のように構成されます。

  • コントローラーの Route 属性でテンプレート文字列を使用します。

    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemsController : ControllerBase
    
  • [controller] をコントローラーの名前 (慣例では "Controller" サフィックスを除くコントローラー クラス名) に置き換えます。 このサンプルでは、コントローラー クラス名は TodoItemsコントローラーであるため、コントローラー名は "TodoItems" です。 ASP.NET Core ルーティング では大文字と小文字が区別されません。

  • [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;
}

戻り値

GetTodoItemsメソッドと GetTodoItem メソッドの戻り値の型は ActionResult<T> 型です。 ASP.NET Core は、オブジェクトを JSON に自動的にシリアル化し、応答メッセージの本文に JSON を書き込みます。 この戻り値の型の応答コードは 200 OK です。ハンドルされない例外がないと仮定します。 ハンドルされない例外は 5xx エラーに変換されます。

ActionResult 戻り値の型は、幅広い範囲の HTTP 状態コードを表すことができます。 たとえば、GetTodoItem は、次の 2 つの異なる状態値を返す可能性があります。

  • 要求された ID と一致する項目がない場合、メソッドは 404 状態NotFound エラー コードを返します。
  • それ以外の場合、メソッドは 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();
}

PutTodoItemPostTodoItem と似ていますが、HTTP PUT を使用します。 応答は 204 (コンテンツなし) です。 HTTP 仕様に従って、PUT 要求では、変更だけでなく、更新されたエンティティ全体を送信するようクライアントに求めます。 部分的な更新をサポートするには、 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 のテストには、他にも使用できるツールが多数あります。次に例を示します。

詳細については、次を参照してください。

過剰な投稿を防止する

現在、サンプル アプリでは TodoItem オブジェクト全体が公開されています。 通常、運用環境のアプリでは、モデルのサブセットを使用して入力されるデータおよび返されるデータが制限されています。 その背景には複数の理由があり、セキュリティは主なものです。 モデルのサブセットは、通常、データ転送オブジェクト (DTO)、入力モデル、またはビュー モデルと呼ばれます。 このチュートリアルでは DTO を使用します。

DTO は次の目的で使用できます。

  • 過剰な投稿を防止する。
  • クライアントが表示しないことになっているプロパティを非表示にする。
  • ペイロード サイズを減らすために、いくつかのプロパティを省略する。
  • 入れ子になったオブジェクトを含むオブジェクト グラフをフラット化する。 フラット化されたオブジェクト グラフは、クライアントにとってより便利になる可能性があります。

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 をセキュリティで保護するには、次のいずれかを使用します。

Duende Identity Server は、ASP.NET Core 用の OpenID Connect および OAuth 2.0 フレームワークです。 Duende Identity Server により、次のセキュリティ機能が有効になります。

  • サービスとしての認証 (AaaS)
  • 複数のアプリケーションの種類でのシングル サインオン/オフ (SSO)
  • API のアクセス制御
  • フェデレーション ゲートウェイ

重要

Duende ソフトウェアでは、DuendeIdentity Server の運用環境での使用に対するライセンス料金の支払いが必要になる場合があります。 詳細については、「 .NET 5 の ASP.NET Core から .NET 6 への移行」を参照してください。

詳細については、 Duende Identity Server のドキュメント (Duende Software Web サイト) を参照してください。

Azure に発行する

Azure へのデプロイの詳細については、「 クイック スタート: ASP.NET Web アプリをデプロイする」を参照してください。

その他の技術情報

このチュートリアルのサンプル コードを表示またはダウンロードしますダウンロードする方法を参照してください。

詳細については、次のリソースを参照してください。