ASP.NET Web API から ASP.NET Core への移行
ASP.NET Core は、ASP.NET 4.x の MVC および Web API アプリ モデルを、ASP.NET Core MVC と呼ばれる単一のプログラミング モデルに結合します。
この記事では、ASP.NET Web API 2 の概要で作成した製品コントローラーを ASP.NET Core に移行する方法について説明します。
前提条件
- Visual Studio 2022 と ASP.NET と Web 開発ワークロード。
- .NET 6.0 SDK
新しい ASP.NET Core Web API プロジェクトを作成する
- [ファイル] メニューで [新規作成]>[プロジェクト] の順に選択します。
- 検索ボックスに「Web API」と入力します。
- [ASP.NET Core Web API] テンプレートを選択し、 [次へ] を選択します。
- [新しいプロジェクトの構成] ダイアログで、プロジェクトに ProductsCore という名前を付けて、[次へ] を選択します。
- [追加情報] ダイアログで、次を行います。
- [フレームワーク] が [.NET 6.0 (長期的なサポート)] になっていることを確認します。
- [コントローラーを使用する (最小限の API を使用する場合はオフにします)] チェック ボックスがオンになっていることを確認します。
- [OpenAPI サポートを有効にする] チェック ボックスをオフにします。
- [作成] を選択します
WeatherForecast テンプレート ファイルを削除する
- 新しい ProductsCore プロジェクトから
WeatherForecast.cs
とControllers/WeatherForecastController.cs
のサンプル ファイルを削除します。 - Properties\launchSettings.json を開きます。
launchUrl
プロパティをweatherforcast
からproductscore
に変更します。
ASP.NET Core Web API の構成
ASP.NET Core では、App_Start フォルダーまたは Global.asax ファイルを使用しません。 web.config ファイルは公開時に追加されます。 詳細については、「web.config ファイル」を参照してください。
Program.cs
ファイルは以下の通りです。
- Global.asax を置き換えます。
- すべてのアプリ スタートアップ タスクを処理します。
詳細については、「ASP.NET Core でのアプリケーションのスタートアップ」をご覧ください。
ASP.NET Core Program.cs
ファイルのアプリケーション スタートアップ コードを次に示します。
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
製品モデルをコピーする
- ソリューション エクスプローラーで、プロジェクトを右クリックします。 [追加]>[新しいフォルダー] の順に選択します。 フォルダーに「Models」という名前を付けます。
- Models フォルダーを右クリックします。 [追加]>[クラス] の順に選択します。 クラスに「製品」という名前を付け、[追加] を選択します。
- テンプレート モデル コードを次のコードに置き換えます。
namespace ProductsCore.Models
{
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Category { get; set; }
public decimal Price { get; set; }
}
}
上記の強調表示されたコードにより、以下が変更されます。
?
注釈が追加され、Name
プロパティとCategory
プロパティが null 許容参照型として宣言されました。
C# 8 で紹介した null 許容機能を利用することで、ASP.NET Core では、参照型の処理においてコード フロー分析が追加され、コンパイル時の安全性を高めることができます。 たとえば、null
参照例外に対する保護を提供します。
この場合の意図は、Name
と Category
を null 許容型にできることです。
ASP.NET Core 6.0 プロジェクトでは、既定で null 許容参照型が有効になります。 詳細については、「null 許容参照型」を参照してください。
ProductsController をコピーする
- Controllers フォルダーを右クリックします。
- [> コントローラーの追加...] を選択します。
- [新規スキャフォールディング アイテムの追加] ダイアログで、[MVC コントローラー - 空][追加] を選択します。
- コントローラーに ProductsController という名前を付け、[追加] を選択します。
- テンプレート コントローラー コードを次のコードに置き換えます。
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
上記の強調表示されたコードは、次のように変更され、ASP.NET Core に移行されます。
ASP.NET Core に存在しない次の ASP.NET 4.x コンポーネントの using ステートメントを削除します。
ApiController
クラスSystem.Web.Http
名前空間IHttpActionResult
インターフェイス
using ProductsApp.Models;
ステートメントをusing ProductsCore.Models;
に変更します。ルート名前空間を
ProductsCore
に設定します。ApiController
を ControllerBase に変更します。using Microsoft.AspNetCore.Mvc;
を追加して、ControllerBase
参照を解決します。GetProduct
アクションの戻り値の型をIHttpActionResult
からActionResult<Product>
に変更します。 詳細については、「コントローラー アクションの戻り値の型」を参照してください。GetProduct
アクションのreturn
ステートメントを次のステートメントに簡略化します。return product;
次のセクションで説明する以下の属性を追加します。
[Route("api/[controller]")]
[ApiController]
[HttpGet]
[HttpGet("{id}")]
ルート指定
ASP.NET Core では、エンドポイント ルーティング ミドルウェアがミドルウェア パイプライン全体をラップする最小限のホスティング モデルが提供されるため、UseEndpoints または UseRouting に対する明示的な呼び出しを行ったり、ルートを登録したりすることなく、WebApplication に直接ルートを追加できます。
UseRouting
は引き続きルート一致が発生する場所を指定するために使用できますが、UseRouting
はミドルウェア パイプラインの先頭でルートを照合する必要がある場合は明示的に呼び出す必要はありません。
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
注: ルートは、パイプラインの "最後" で、WebApplication execute に直接追加されます。
移行された ProductsController
でのルーティング
移行された ProductsController
には、次の強調表示された属性が含まれます。
using Microsoft.AspNetCore.Mvc;
using ProductsCore.Models;
namespace ProductsCore.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
[HttpGet]
public IEnumerable<Product> GetAllProducts()
{
return products;
}
[HttpGet("{id}")]
public ActionResult<Product> GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return product;
}
}
[Route]
属性では、コントローラーの属性ルーティング パターンを構成します。[ApiController]
属性により、属性ルーティングは、このコントローラー内のすべてのアクションの要件になります。属性ルーティングでは、
[controller]
や[action]
などのトークンがサポートされます。 実行時、各トークンはそれぞれ、属性が適用されたコントローラーまたはアクションの名前に置き換えられます。 トークンには次の利点があります。- ルートにハード コーディングされた文字列を使用する必要性を減らすか、不要にします。
- 自動的な名前変更時のリファクタリングが適用された場合、ルートと、対応するコントローラーおよびアクションとの同期が確実に維持されます。
HTTP Get 要求は、次の属性を持つ
ProductController
アクションに対して有効になります。[HttpGet]
属性がGetAllProducts
アクションに適用されました。[HttpGet("{id}")]
属性がGetProduct
アクションに適用されました。
移行したプロジェクトを実行し、/api/products
を参照します。 例: https://localhost:<port>
/api/products。 3 つの製品の完全なリストが表示されます。 [https://www.microsoft.com](/api/products/1
) を参照します。 最初の製品が表示されます。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
その他のリソース
この記事では、ASP.NET 4.x Web API から ASP.NET Core MVC に移行するために必要な手順について説明します。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
前提条件
- ASP.NET および Web 開発ワークロードを含む Visual Studio 2019 16.4 以降
- .NET Core 3.1 SDK
ASP.NET 4.x Web API プロジェクトを確認する
この記事では、「ASP.NET Web API 2 の概要」で作成した ProductsApp プロジェクトを使用します。 このプロジェクトでは、基本の ASP.NET 4.x Web API プロジェクトは次のように構成されています。
Global.asax.cs
で、WebApiConfig.Register
が呼び出されます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
namespace ProductsApp
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
WebApiConfig
クラスは、App_Start フォルダー内にあり、静的な Register
メソッドが含まれています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace ProductsApp
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
前の クラスは次のとおりです。
- 属性ルーティングの構成。ただし、実際には使用されません。
- ルーティング テーブルの構成。
サンプル コードでは、URL が
/api/{controller}/{id}
の形式と一致することを想定しています。{id}
は省略できます。
以下のセクションでは、Web API プロジェクトを ASP.NET Core MVC に移行する方法について説明します。
移行先のプロジェクトを作成する
Visual Studio で新しい空のソリューションを作成し、移行する ASP.NET 4.x Web API プロジェクトを追加します。
- [ファイル] メニューで [新規作成]>[プロジェクト] の順に選択します。
- [空のソリューション] テンプレートを選択し、[次へ] を選択します。
- ソリューションに WebAPIMigrationという名前を付けます。 [作成] を選択します
- 既存の ProductsApp プロジェクトをソリューションに追加します。
移行先の新しい API プロジェクトを追加します。
- 新しい ASP.NET Core Web Application プロジェクトをソリューションに追加します。
- [新しいプロジェクトの構成] ダイアログで、プロジェクトに ProductsCore という名前を付けて、[作成] を選択します。
- [新しい ASP.NET Core Web アプリケーションを作成する] ダイアログで、 [.NET Core] と [ASP.NET Core 3.1] が選択されていることを確認します。 [API] プロジェクト テンプレートを選択し、 [作成] を選択します。
- 新しい ProductsCore プロジェクトから
WeatherForecast.cs
とControllers/WeatherForecastController.cs
のサンプル ファイルを削除します。
以上で、ソリューションに 2 つのプロジェクトが含まれました。 以降のセクションでは、ProductsApp プロジェクトの内容を ProductsCore プロジェクトに移行する方法について説明します。
構成の移行
ASP.NET Core では、App_Start フォルダーまたは Global.asax ファイルを使用しません。 さらに、web.config ファイルは、公開時に追加されます。
Startup
クラス:
- Global.asax を置き換えます。
- すべてのアプリ スタートアップ タスクを処理します。
詳細については、「ASP.NET Core でのアプリケーションのスタートアップ」をご覧ください。
モデルとコントローラーを移行する
次のコードは、ASP.NET Core 用に更新される ProductsController
を示しています。
using ProductsApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
namespace ProductsApp.Controllers
{
public class ProductsController : ApiController
{
Product[] products = new Product[]
{
new Product
{
Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1
},
new Product
{
Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M
},
new Product
{
Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M
}
};
public IEnumerable<Product> GetAllProducts()
{
return products;
}
public IHttpActionResult GetProduct(int id)
{
var product = products.FirstOrDefault((p) => p.Id == id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}
}
ProductsController
を ASP.NET Core 用に更新します。
Controllers/ProductsController.cs
と Models フォルダーを元のプロジェクトから新しいプロジェクトにコピーします。- コピーしたファイルのルート名前空間を
ProductsCore
に変更します。 using ProductsApp.Models;
ステートメントをusing ProductsCore.Models;
に更新します。
ASP.NET Core には、次のコンポーネントはありません。
ApiController
クラスSystem.Web.Http
名前空間IHttpActionResult
インターフェイス
次の変更を行います。
ApiController
を ControllerBase に変更します。using Microsoft.AspNetCore.Mvc;
を追加して、ControllerBase
参照を解決します。using System.Web.Http;
を削除します。GetProduct
アクションの戻り値の型をIHttpActionResult
からActionResult<Product>
に変更します。GetProduct
アクションのreturn
ステートメントを次のように簡略化します。return product;
ルーティングを構成する
ASP.NET Core API プロジェクト テンプレートには、生成されたコードにエンドポイント ルーティング構成が含まれます。
次の UseRouting および UseEndpoints の呼び出しでは、次のことを行います。
- ルートの一致とエンドポイントの実行をミドルウェア パイプラインに登録します。
- ProductsApp プロジェクトの
App_Start/WebApiConfig.cs
ファイルを置き換えます。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
ルーティングを次のように構成します。
ProductsController
を次の属性でマークします。[Route("api/[controller]")] [ApiController]
前述の
[Route]
属性では、コントローラーの属性ルーティング パターンを構成します。[ApiController]
属性により、属性ルーティングは、このコントローラー内のすべてのアクションの要件になります。属性ルーティングでは、
[controller]
や[action]
などのトークンがサポートされます。 実行時、各トークンはそれぞれ、属性が適用されたコントローラーまたはアクションの名前に置き換えられます。 トークンには次の利点があります。- プロジェクト内のマジック文字列の数が削減されます。
- 自動的な名前変更時のリファクタリングが適用された場合、ルートと、対応するコントローラーおよびアクションとの同期が確実に維持されます。
ProductsController
アクションに対する HTTP Get 要求を有効にします。[HttpGet]
属性をGetAllProducts
アクションに適用します。[HttpGet("{id}")]
属性をGetProduct
アクションに適用します。
移行したプロジェクトを実行し、/api/products
を参照します。 3 つの製品の完全なリストが表示されます。 [https://www.microsoft.com](/api/products/1
) を参照します。 最初の製品が表示されます。
その他のリソース
ASP.NET Core