ASP.NET Core 2.2 から 3.0 への移行

作成者: Scott AddieRick Anderson

この記事では、既存の ASP.NET Core 2.2 プロジェクトを ASP.NET Core 3.0 に更新する方法について説明します。 以下を行う際に、新しい ASP.NET Core 3.0 プロジェクトを作成すると、便利な場合があります。

  • ASP.NET Core 2.2 コードと比較する。
  • 関連する変更を ASP.NET Core 3.0 プロジェクトにコピーする。

前提条件

global.json での .NET Core SDK バージョンの更新

使用するソリューションが global.json ファイルに依存して、特定の .NET Core SDK バージョンをターゲットにしている場合、その version プロパティを、コンピューターにインストールされている 3.0 バージョンに更新します。

{
  "sdk": {
    "version": "3.0.100"
  }
}

プロジェクト ファイルの更新

ターゲット フレームワークを更新する

ASP.NET Core 3.0 以降は、.NET Core でのみ実行されます。 ターゲット フレームワーク モニカー (TFM)netcoreapp3.0 です。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

古いパッケージ参照を削除する

NuGet パッケージの数が多いと ASP.NET Core 3.0 では生成されません。 このようなパッケージ参照は、プロジェクト ファイルから削除する必要があります。 ASP.NET Core 2.2 Web アプリの場合は、次のプロジェクト ファイルを検討してください。

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
  </ItemGroup>

</Project>

ASP.NET Core 3.0 用に更新されたファイル:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>

</Project>

更新された ASP.NET Core 3.0 プロジェクト ファイル:

  • <PropertyGroup> では、次のことが行われます。

  • <ItemGroup> では、次のことが行われます。

    • Microsoft.AspNetCore.App が削除されます。 詳細については、このドキュメントの「フレームワーク参照」を参照してください。
    • Microsoft.AspNetCore.Razor.Design が削除され、以下の生成されなくなったパッケージの一覧に含められています。

生成されなくなったパッケージの完全な一覧を表示するには、次のリストの展開を選択してください。

クリックして、生成されなくなったパッケージの一覧を展開します
  • Microsoft.AspNetCore
  • Microsoft.AspNetCore.All
  • Microsoft.AspNetCore.App
  • Microsoft.AspNetCore.Antiforgery
  • Microsoft.AspNetCore.Authentication
  • Microsoft.AspNetCore.Authentication.Abstractions
  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.Core
  • Microsoft.AspNetCore.Authentication.OAuth
  • Microsoft.AspNetCore.Authorization.Policy
  • Microsoft.AspNetCore.CookiePolicy
  • Microsoft.AspNetCore.Cors
  • Microsoft.AspNetCore.Diagnostics
  • Microsoft.AspNetCore.Diagnostics.HealthChecks
  • Microsoft.AspNetCore.HostFiltering
  • Microsoft.AspNetCore.Hosting
  • Microsoft.AspNetCore.Hosting.Abstractions
  • Microsoft.AspNetCore.Hosting.Server.Abstractions
  • Microsoft.AspNetCore.Http
  • Microsoft.AspNetCore.Http.Abstractions
  • Microsoft.AspNetCore.Http.Connections
  • Microsoft.AspNetCore.Http.Extensions
  • Microsoft.AspNetCore.HttpOverrides
  • Microsoft.AspNetCore.HttpsPolicy
  • Microsoft.AspNetCore.Identity は、
  • Microsoft.AspNetCore.Localization
  • Microsoft.AspNetCore.Localization.Routing
  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.Mvc.Abstractions
  • Microsoft.AspNetCore.Mvc.Analyzers
  • Microsoft.AspNetCore.Mvc.ApiExplorer
  • Microsoft.AspNetCore.Mvc.Api.Analyzers
  • Microsoft.AspNetCore.Mvc.Core
  • Microsoft.AspNetCore.Mvc.Cors
  • Microsoft.AspNetCore.Mvc.DataAnnotations
  • Microsoft.AspNetCore.Mvc.Formatters.Json
  • Microsoft.AspNetCore.Mvc.Formatters.Xml
  • Microsoft.AspNetCore.Mvc.Localization
  • Microsoft.AspNetCore.Mvc.Razor
  • Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
  • Microsoft.AspNetCore.Mvc.RazorPages
  • Microsoft.AspNetCore.Mvc.TagHelpers
  • Microsoft.AspNetCore.Mvc.ViewFeatures
  • Microsoft.AspNetCore.Razor は、
  • Microsoft.AspNetCore.Razor.Runtime
  • Microsoft.AspNetCore.Razor.Design
  • Microsoft.AspNetCore.ResponseCaching
  • Microsoft.AspNetCore.ResponseCaching.Abstractions
  • Microsoft.AspNetCore.ResponseCompression
  • Microsoft.AspNetCore.Rewrite
  • Microsoft.AspNetCore.Routing
  • Microsoft.AspNetCore.Routing.Abstractions
  • Microsoft.AspNetCore.Server.HttpSys
  • Microsoft.AspNetCore.Server.IIS
  • Microsoft.AspNetCore.Server.IISIntegration
  • Microsoft.AspNetCore.Server.Kestrel
  • Microsoft.AspNetCore.Server.Kestrel.Core
  • Microsoft.AspNetCore.Server.Kestrel.Https
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets
  • Microsoft.AspNetCore.Session
  • Microsoft.AspNetCore.SignalR は、
  • Microsoft.AspNetCore.SignalR.Core
  • Microsoft.AspNetCore.StaticFiles
  • Microsoft.AspNetCore.WebSockets
  • Microsoft.AspNetCore.WebUtilities
  • Microsoft.Net.Http.Headers

破壊的変更の確認

破壊的変更の確認

フレームワーク参照

上記のパッケージのいずれかを使用して利用できた ASP.NET Core の機能は、Microsoft.AspNetCore.App 共有フレームワークの一部として入手できます。 共有フレームワークは、コンピューター上にインストールされたアセンブリ (.dll ファイル) のセットであり、ランタイム コンポーネントと Targeting Pack を含みます。 詳しくは、共有フレームワークに関するページをご覧ください。

  • Microsoft.NET.Sdk.Web SDK を対象とするプロジェクトは、Microsoft.AspNetCore.App フレームワークを暗黙に参照します。

    これらのプロジェクトには、追加の参照は必要ありません。

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
        ...
    </Project>
    
  • Microsoft.NET.Sdk または Microsoft.NET.Sdk.Razor SDK を対象とするプロジェクトでは、次のように FrameworkReferenceMicrosoft.AspNetCore.App に明示的に追加する必要があります。

    <Project Sdk="Microsoft.NET.Sdk.Razor">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
        ...
    </Project>
    

Docker を使用したフレームワーク依存のビルド

ASP.NET Core 共有フレームワークに依存するパッケージを使用する、フレームワーク依存のコンソール アプリのビルドでは、次のランタイム エラーが発生する可能性があります。

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '3.0.0' was not found.
  - No frameworks were found.

Microsoft.AspNetCore.App は ASP.NET Core ランタイムを含む共有フレームワークであり、dotnet/core/aspnet Docker イメージにのみ存在します。 3.0 SDK では、共有フレームワークで使用できるライブラリの重複コピーを含まないことによって、ASP.NET Core を使用するフレームワーク依存のビルドのサイズを縮小します。 これは最大 18 MB に抑えられる可能性がありますが、アプリを実行するには ASP.NET Core ランタイムが存在し、インストールされている必要があります。

アプリが ASP.NET Core 共有フレームワークに依存 (直接または間接的のいずれか) するかどうかを判断するには、アプリのビルドまたは発行中に生成された runtimeconfig.json ファイルを調べます。 次の JSON ファイルには、ASP.NET Core 共有フレームワークに依存していることが示されています。

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.0",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "3.0.0"
    },
    "configProperties": {
      "System.GC.Server": true
    }
  }
}

Docker を使用しているアプリでは、ASP.NET Core 3.0 を含む基本イメージを使用しています。 たとえば、「 docker pull mcr.microsoft.com/dotnet/core/aspnet:3.0 」のように入力します。

削除されたアセンブリのパッケージ参照を追加する

ASP.NET Core 3.0 では、以前に Microsoft.AspNetCore.App パッケージ参照の一部であった一部のアセンブリが削除されます。 削除されたアセンブリを視覚化するには、2 つの共有フレームワーク フォルダーを比較します。 たとえば、2.2.7 と 3.0.0 バージョンの比較を次に示します。

共有フレームワーク アセンブリの比較

削除されたアセンブリによって提供される機能を引き続き使用するには、対応するパッケージの 3.0 バージョンを参照してください。

スタートアップの変更

次の図は、ASP.NET Core 2.2 Razor Pages Web アプリの削除および変更された行を示しています。

ASP.NET Core 2.2 Razor Web アプリで削除された行と変更された行

上の図では、削除されたコードは赤色で示されています。 削除されたコードに、ファイルを比較する前に削除された cookie オプション コードは示されていません。

次の図は、ASP.NET Core 3.0 Razor Pages Web アプリで追加および変更された行を示しています。

ASP.NET Core 3.0 Razor Web アプリで追加された行と変更された行

上の図では、追加されたコードは緑色で示されています。 以下の変更については、それぞれの参照先をご覧ください。

  • services.AddMvc から services.AddRazorPages については、このドキュメントの「MVC サービス登録」を参照してください。
  • CompatibilityVersion については、「ASP.NET Core MVC の互換バージョン」を参照してください。
  • IHostingEnvironment から IWebHostEnvironment については、こちらの GitHub のお知らせを参照してください。
  • app.UseAuthorization は、承認ミドルウェアを追加しなければならない順序を示すために、テンプレートに追加されました。 アプリが承認を使用しない場合は、app.UseAuthorization の呼び出しを安全に削除できます。
  • app.UseEndpoints については、このドキュメントの「Razor Pages」または「Startup.Configure に移行する」を参照してください。

アナライザーのサポート

Microsoft.NET.Sdk.Web を対象とするプロジェクトは、以前に Microsoft.AspNetCore.Mvc.Analyzers パッケージの一部として同梱されていたアナライザーを暗黙的に参照します。 これらを有効にするために、参照を追加する必要はありません。

以前に Microsoft.AspNetCore.Mvc.Api.Analyzers パッケージを使用して同梱されていた API アナライザーをアプリで使用する場合は、.NET Core Web SDK の一部として同梱されるアナライザーを参照するようにプロジェクト ファイルを編集します。

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <IncludeOpenAPIAnalyzers>true</IncludeOpenAPIAnalyzers>
    </PropertyGroup>

    ...
</Project>

Razor クラス ライブラリ

MVC の UI コンポーネントを提供する Razor クラス ライブラリ プロジェクトでは、プロジェクト ファイルで AddRazorSupportForMvc プロパティを設定する必要があります。

<PropertyGroup>
  <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</PropertyGroup>

インプロセス ホスティング モデル

ASP.NET Core 3.0 以降では、プロジェクトの既定値はインプロセス ホスティング モデルとなります。 プロジェクト ファイルの <AspNetCoreHostingModel> プロパティの値が InProcess の場合は、そのプロパティを削除することもできます。

Kestrel

構成

Kestrel 構成を ConfigureWebHostDefaults (Program.cs) によって提供される Web ホスト ビルダーに移行します。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseStartup<Startup>();
        });

アプリが ConfigureWebHostDefaults の代わりに、ConfigureWebHost を使用して手動でホストを作成する場合は、Web ホスト ビルダーで UseKestrel を呼び出します。

public static void Main(string[] args)
{
    var host = new HostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder.UseKestrel(serverOptions =>
            {
                // Set properties and call methods on options
            })
            .UseIISIntegration()
            .UseStartup<Startup>();
        })
        .Build();

    host.Run();
}

接続ミドルウェアが接続アダプターに置き換わる

接続アダプター (Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal.IConnectionAdapter) は Kestrel から削除されました。 接続アダプターを接続ミドルウェアに置き換えます。 接続ミドルウェアは、ASP.NET Core パイプラインの HTTP ミドルウェアに似ていますが、下位レベルの接続に使用されます。 HTTPS および接続のログは、

  • 接続アダプターから接続ミドルウェアに移動されました。
  • これらの拡張メソッドは、以前のバージョンの ASP.NET Core と同様に機能します。

詳細については、記事「Kestrel」の ListenOptions.Protocols に関するセクションの TlsFilterConnectionHandler の例を参照してください。

トランスポートの抽象化が削除されて公開された

Kestrel トランスポート層は、Connections.Abstractions のパブリック インターフェイスとして公開されています。 更新プログラムの一部として、

  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions および関連する型が削除されました。
  • NoDelayListenOptions からトランスポート オプションに移動されました。
  • Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal.SchedulingModeKestrelServerOptions から削除されました。

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

Kestrel 要求トレーラー ヘッダー

以前のバージョンの ASP.NET Core を対象とするアプリの場合:

  • Kestrel は HTTP/1.1 チャンク トレーラー ヘッダーを要求ヘッダー コレクションに追加します。
  • トレーラーは、要求本文が最後に読み取られた後に使用できるようになります。

これにより、ヘッダーとトレーラーのあいまいさに関していくつかの懸念事項が生じるため、3.0 ではトレーラーは新しいコレクション (RequestTrailerExtensions) に移動されました。

HTTP/2 要求のトレーラーは、

  • ASP.NET Core 2.2 では使用できません。
  • 3.0 では RequestTrailerExtensions として使用できます。

これらのトレーラーにアクセスするための新しい要求拡張メソッドがあります。 HTTP/1.1 と同様、トレーラーは、要求本文が最後に読み取られた後に使用できるようになります。

3.0 リリースでは、次の RequestTrailerExtensions メソッドが使用できます。

  • GetDeclaredTrailers: 本文の後に予想されるトレーラーを示す、要求の Trailer ヘッダーを取得します。
  • SupportsTrailers: 要求でトレーラー ヘッダーの受信がサポートされているかどうかを示します。
  • CheckTrailersAvailable: 要求でトレーラーがサポートされているかどうか、読み取られるトレーラーがあるかどうかを確認します。 このチェックでは、読み取るトレーラーがあることは想定していません。 このメソッドによって true が返された場合でも、読み取るトレーラーは存在しない可能性があります。
  • GetTrailer: 要求された末尾のヘッダーを応答から取得します。 GetTrailer を呼び出す前に SupportsTrailers を確認します。要求が後続のヘッダーをサポートしていない場合は、NotSupportedException が発生することがあります。

詳細については、「別のコレクションに要求トレーラーを配置する (dotnet/AspNetCore #10410)」を参照してください。

AllowSynchronousIO の無効化

AllowSynchronousIOHttpRequest.Body.ReadHttpResponse.Body.WriteStream.Flush などの同期 I/O API を有効または無効にします。 これらの API は、アプリのクラッシュにつながるスレッドの枯渇の原因となります。 3\.0 では、AllowSynchronousIO は既定で無効になっています。 詳細については、「Kestrel」の同期 I/O に関するセクションを参照してください。

同期 I/O が必要な場合は、使用するサーバーで AllowSynchronousIO オプションを構成することによってその API を有効にできます (たとえば、Kestrel を使用している場合は ConfigureKestrel を呼び出します)。 サーバー (Kestrel、HttpSys、TestServer など) には、他のサーバーに影響を与えない独自の AllowSynchronousIO オプションがあることに注意してください。 IHttpBodyControlFeature.AllowSynchronousIO オプションを使用して、すべてのサーバーに対して、要求ごとに同期 I/O を有効にすることができます。

var syncIOFeature = HttpContext.Features.Get<IHttpBodyControlFeature>();

if (syncIOFeature != null)
{
    syncIOFeature.AllowSynchronousIO = true;
}

TextWriter の実装、または Dispose で同期 API を呼び出す別のストリームで問題が発生した場合は、代わりに新しい DisposeAsync API を呼び出します。

詳細については、「[お知らせ] AllowSynchronousIO はすべてのサーバーで無効になっています (dotnet/AspNetCore #7644)」を参照してください。

出力フォーマッタのバッファリング

Newtonsoft.JsonXmlSerializer、および DataContractSerializer ベースの出力フォーマッタでは、同期シリアル化のみがサポートされます。 これらのフォーマッタがサーバーの AllowSynchronousIO 制限を処理できるようにするために、MVC はディスクに書き込む前にこれらのフォーマッタの出力をバッファーします。 バッファリングの結果として、MVC では、これらのフォーマッタを使用して応答するときに Content-length ヘッダーがインクルードされます。

System.Text.Json は、非同期のシリアル化をサポートします。そのため、System.Text.Json ベースのフォーマッタはバッファーを作成しません。 パフォーマンスを向上させるために、このフォーマッタの使用を検討してください。

バッファリングを無効にするには、アプリケーションの起動時に SuppressOutputFormatterBuffering を構成できます。

services.AddControllers(options => options.SuppressOutputFormatterBuffering = true)

これにより、AllowSynchronousIO も構成されていないと、アプリケーションがランタイム例外をスローする可能性があることに注意してください。

Microsoft.AspNetCore.Server.Kestrel.Https アセンブリが削除された

ASP.NET Core 2.1 では、Microsoft.AspNetCore.Server.Kestrel.Https.dll のコンテンツが Microsoft.AspNetCore.Server.Kestrel.Core.dll に移動されました。 これは、TypeForwardedTo 属性を使用した非破壊的な更新です。 3.0 では、空の Microsoft.AspNetCore.Server.Kestrel.Https.dll アセンブリと NuGet パッケージが削除されました。

Microsoft.AspNetCore.Server.Kestrel.Https を参照するライブラリでは、ASP.NET Core の依存関係を 2.1 以降に更新する必要があります。

ASP.NET Core 2.1 以降を対象とするアプリとライブラリでは、Microsoft.AspNetCore.Server.Kestrel.Https パッケージへの直接参照をすべて削除する必要があります。

Newtonsoft.Json (Json.NET) のサポート

ASP.NET Core 共有フレームワークを改善する作業の一環として、ASP.NET Core 共有フレームワークから Newtonsoft.Json (Json.NET) が削除されました。

ASP.NET Core の既定の JSON シリアライザーは System.Text.Json で、.NET Core 3.0 で新たに追加されたものです。 可能な場合は、System.Text.Json の使用を検討してください。 パフォーマンスが高く、ライブラリの依存関係を追加する必要はありません。 ただし、System.Text.Json は新しい機能のため、アプリに必要な機能が不足している可能性があります。 詳細については、「Newtonsoft.Json から System.Text.Json に移行する方法」を参照してください。

ASP.NET Core 3.0 SignalR プロジェクトで Newtonsoft.Json を使用する

  • Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson NuGet パッケージをインストールします。

  • クライアントで、AddNewtonsoftJsonProtocol メソッドの呼び出しを HubConnectionBuilder インスタンスに連結します。

    new HubConnectionBuilder()
        .WithUrl("/chathub")
        .AddNewtonsoftJsonProtocol(...)
        .Build();
    
  • サーバーで、AddNewtonsoftJsonProtocol メソッドの呼び出しを Startup.ConfigureServices での AddSignalR メソッドの呼び出しに連結します。

    services.AddSignalR()
        .AddNewtonsoftJsonProtocol(...);
    

ASP.NET Core 3.0 MVC プロジェクトで Newtonsoft.Json を使用する

  • Microsoft.AspNetCore.Mvc.NewtonsoftJson パッケージをインストールします。

  • AddNewtonsoftJson を呼び出すように Startup.ConfigureServices を更新します。

    services.AddMvc()
        .AddNewtonsoftJson();
    

    AddNewtonsoftJson は新しい MVC サービス登録メソッドと互換性があります。

    • AddRazorPages
    • AddControllersWithViews
    • AddControllers
    services.AddControllers()
        .AddNewtonsoftJson();
    

    Newtonsoft.Json の設定は、AddNewtonsoftJson の呼び出しで設定できます。

    services.AddMvc()
        .AddNewtonsoftJson(options =>
               options.SerializerSettings.ContractResolver =
                  new CamelCasePropertyNamesContractResolver());
    

    注: AddNewtonsoftJson メソッドが使用できない場合は、Microsoft.AspNetCore.Mvc.NewtonsoftJson パッケージがインストールされていることを確認してください。 一般的なエラーとして、Microsoft.AspNetCore.Mvc.NewtonsoftJson パッケージではなく Newtonsoft.Json パッケージをインストールしていることがあります。

詳細については、「Newtonsoft.Json ベースの JSON 形式のサポートを追加する」を参照してください。

MVC サービス登録

ASP.NET Core 3.0 では、Startup.ConfigureServices 内に MVC シナリオを登録するための新しいオプションが追加されています。

IServiceCollection の MVC シナリオに関連する 3 つの新しい最上位レベルの拡張メソッドを使用できます。 テンプレートでは、AddMvc ではなく、これらの新しいメソッドを使用します。 ただし、AddMvc は、これまでのリリースと同じように動作します。

次の例では、コントローラーと API 関連の機能のサポートを追加しますが、ビューやページはサポートしません。 API テンプレートでは、次のコードを使用します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

次の例では、コントローラー、API 関連の機能、およびビューのサポートを追加しますが、ページはサポートしません。 Web アプリケーション (MVC) テンプレートでは、次のコードを使用します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
}

次の例では、Razor Pages のサポートとコントローラーの最低限のサポートを追加します。 Web アプリケーション テンプレートでは、次のコードを使用します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
}

新しいメソッドを組み合わせることもできます。 次の例は ASP.NET Core 2.2 で AddMvc を呼び出すのと同等です。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

スタートアップ コードのルーティング

アプリが UseMvc または UseSignalR を呼び出す場合は、可能であれば、エンドポイント ルーティングにアプリを移行します。 MVC の以前のバージョンとのエンドポイント ルーティングの互換性を向上させるために、ASP.NET Core 2.2 で導入された URL 生成の一部の変更を元に戻しました。 2.2 でエンドポイント ルーティングを使用するときに問題が発生した場合、次の例外を適用することで ASP.NET Core 3.0 で改善が見られることが期待されています。

  • アプリが IRouter を実装しているか、Route から継承している場合は、DynamicRouteValuesTransformer を代わりに使用します。
  • URL を解析するためにアプリが MVC 内で RouteData.Routers に直接アクセスする場合は、これを LinkParser.ParsePathByEndpointName を使用するように置き換えることができます。
    • ルート名を使用してルートを定義します。
    • LinkParser.ParsePathByEndpointName を使用し、目的のルート名を渡します。

エンドポイント ルーティングでは、IRouter と同じルート パターン構文とルート パターン オーサリング機能がサポートされています。 エンドポイント ルーティングでは、IRouteConstraint がサポートされます。 エンドポイント ルーティングでは、[Route][HttpGet]、およびその他の MVC ルーティング属性がサポートされます。

ほとんどのアプリケーションでは、Startup の変更が必要になるだけです。

Startup.Configure を移行する

一般的なアドバイス:

  • UseRoutingを追加します。

  • アプリによって UseStaticFiles が呼び出される場合、UseStaticFilesUseRoutingに配置します。

  • アプリが AuthorizePage[Authorize] などの認証/承認機能を使用する場合は、UseAuthenticationUseAuthorization の呼び出しを UseRoutingUseCors、しかし UseEndpoints の前に配置します。

    public void Configure(IApplicationBuilder app)
    {
      ...
    
      app.UseStaticFiles();
    
      app.UseRouting();
      app.UseCors();
    
      app.UseAuthentication();
      app.UseAuthorization();
    
      app.UseEndpoints(endpoints => {
         endpoints.MapControllers();
      });
    
  • UseMvc または UseSignalRUseEndpoints に置き換えます。

  • アプリで [EnableCors] などの CORS シナリオを使用する場合は、UseCors の呼び出しを CORS を使用する他のミドルウェアの前に配置します (たとえば、UseAuthenticationUseAuthorizationUseEndpoints の前に UseCors を配置します)。

  • Microsoft.AspNetCore.Hosting 名前空間のために、IHostingEnvironmentIWebHostEnvironment で置き換え、using ステートメントを追加します。

  • IApplicationLifetimeIHostApplicationLifetime に置き換えます (Microsoft.Extensions.Hosting)。

  • EnvironmentNameEnvironments に置き換えます (Microsoft.Extensions.Hosting)。

次のコードは、一般的な ASP.NET Core 2.2 アプリにおける Startup.Configure の例です。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseAuthentication();

    app.UseSignalR(hubs =>
    {
        hubs.MapHub<ChatHub>("/chat");
    });

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

上の Startup.Configure コードを更新した後:

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseStaticFiles();

    app.UseRouting();

    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/chat");
        endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
}

警告

ほとんどのアプリでは、UseAuthenticationUseAuthorization、および UseCors への呼び出しを有効にするため、UseRoutingUseEndpoints の間に配置する必要があります。

正常性チェック

正常性チェックでは、汎用ホストとのエンドポイント ルーティングを使用します。 Startup.Configure で、エンドポイントの URL または相対パスを使用して、エンドポイント ビルダーで MapHealthChecks を呼び出します。

app.UseEndpoints(endpoints =>
{
    endpoints.MapHealthChecks("/health");
});

正常性チェックのエンドポイントは以下を行うことができます。

  • 1 つまたは複数の許可されたホスト/ポートを指定する。
  • 承認を必要とする。
  • CORS を必要とする。

詳細については、「Health checks in ASP.NET Core」(ASP.NET Core の正常性チェック) を参照してください。

セキュリティ ミドルウェアのガイダンス

承認と CORS のサポートは、ミドルウェア アプローチに関連して統合されています。 これにより、これらのシナリオで同じミドルウェアと機能を使用できるようになります。 このリリースでは、更新された承認ミドルウェアが提供されており、また CORS ミドルウェアが拡張され、MVC コントローラーで使用される属性を理解できるようになりました。

CORS

以前は、CORS の構成は困難でした。 ミドルウェアは一部のユース ケースで使用するために提供されていましたが、MVC フィルターは他のユース ケースでミドルウェアなしで使用することが意図されていました。 ASP.NET Core 3.0 では、CORS を必要とするすべてのアプリで、エンドポイント ルーティングと連携させて CORS ミドルウェアを使用することをお勧めします。 UseCors は既定のポリシーで指定できます。また必要に応じて、[EnableCors][DisableCors] 属性を使用して既定のポリシーを上書きすることもできます。

次に例を示します。

  • CORS は、default 名前付きポリシーで、すべてのエンドポイントに対して有効にされています。
  • MyController クラスは [DisableCors] 属性で CORS を無効にしています。
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseCors("default");

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[DisableCors]
public class MyController : ControllerBase
{
    ...
}

承認

以前のバージョンの ASP.NET Core では、[Authorize] 属性を介して承認のサポートが提供されていました。 承認ミドルウェアは使用できませんでした。 ASP.NET Core 3.0 では、承認ミドルウェアが必要です。 ASP.NET Core の承認ミドルウェア (UseAuthorization) は、UseAuthentication の直後に配置することをお勧めします。 承認ミドルウェアは、上書き可能な既定のポリシーを使用して構成することもできます。

ASP.NET Core 3.0 以降では、UseAuthorizationStartup.Configure で呼び出されます。次の HomeController では、サインイン ユーザーが必要です。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

public class HomeController : Controller
{
    [Authorize]
    public IActionResult BuyWidgets()
    {
        ...
    }
}

エンドポイント ルーティングを使用する場合は、AuthorizeFilter を構成することはお勧めしません。承認ミドルウェアをご利用ください。 アプリで MVC のグローバル フィルターとして AuthorizeFilter を使用する場合は、AddAuthorization の呼び出しでポリシーを提供するように、コードをリファクタリングすることをお勧めします。

DefaultPolicy は、最初から認証を要求するように構成されているため、追加の構成は必要ありません。 次の例では、MVC エンドポイントは RequireAuthorization としてマークされるため、すべての要求が DefaultPolicy に基づいて承認される必要があります。 ただし、HomeController では、[AllowAnonymous] があるため、ユーザーがアプリにサインインしなくてもアクセスできます。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute().RequireAuthorization();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

特定のエンドポイントの承認

承認は、特定のクラスのエンドポイントに対して構成することもできます。 次のコードは、グローバルの AuthorizeFilter が構成された MVC アプリを、承認を必要とする特定のポリシーを使用するアプリに変換する例です。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    static readonly string _RequireAuthenticatedUserPolicy = 
                            "RequireAuthenticatedUserPolicy";
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // Pre 3.0:
        // services.AddMvc(options => options.Filters.Add(new AuthorizeFilter(...));

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(o => o.AddPolicy(_RequireAuthenticatedUserPolicy,
                        builder => builder.RequireAuthenticatedUser()));

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute()
                .RequireAuthorization(_RequireAuthenticatedUserPolicy);
            endpoints.MapRazorPages();
        });
    }
}

ポリシーをカスタマイズすることもできます。 DefaultPolicy は認証を要求するように構成されています。

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(
                 options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();
        services.AddAuthorization(options =>
        {
            options.DefaultPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .Build();
        });

    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute().RequireAuthorization();
            endpoints.MapRazorPages();
        });
    }
}
[AllowAnonymous]
public class HomeController : Controller
{

あるいは、FallbackPolicy 構成することで、[Authorize] または RequireAuthorization なしに承認を要求するようにすべてのエンドポイントを構成できます。 FallbackPolicy は、DefaultPolicy とは異なります。 DefaultPolicy[Authorize] または RequireAuthorization によってトリガーされますが、他のポリシーが設定されていない場合は FallbackPolicy がトリガーされます。 FallbackPolicy は、承認されていない要求を許可するように最初から構成されています。

次の例は上の DefaultPolicy の例と同じですが、[AllowAnonymous] を指定した場合を除き、すべてのエンドポイントで必ず認証が必要になるように、FallbackPolicy を使用しています。

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddAuthorization(options =>
    {
        options.FallbackPolicy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();
    });
}

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

[AllowAnonymous]
public class HomeController : Controller
{
    ...
}

ミドルウェアによる承認は、フレームワークに承認に関する特定の情報を持たせなくても機能します。 たとえば、正常性チェックには承認に関する特定の情報はありませんが、ミドルウェアによって適用される構成可能な承認ポリシーを設定できます。

さらに、各エンドポイントで承認要件をカスタマイズできます。 次の例では、UseAuthorizationDefaultPolicy を使用して承認を処理しますが、/healthz 正常性チェックのエンドポイントには admin ユーザーが必要です。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints
            .MapHealthChecks("/healthz")
            .RequireAuthorization(new AuthorizeAttribute(){ Roles = "admin", });
    });
}

一部のシナリオでは、保護が実装されます。 ミドルウェアが不足しているために、承認ポリシーまたは CORS ポリシーがスキップされた場合、エンドポイント ミドルウェアは例外をスローします。 構成の誤りに関する追加のフィードバックを提供するアナライザーのサポート計画が進行中です。

カスタム承認ハンドラー

アプリがカスタム承認ハンドラーを使用する場合、エンドポイント ルーティングは、MVC とは異なるリソースの種類をハンドラーに渡します。 承認ハンドラー コンテキスト リソースの型が AuthorizationFilterContext (MVC フィルターによって提供されるリソースの種類) であることを想定するハンドラーは、型 RouteEndpoint (エンドポイント ルーティングによって承認ハンドラーに指定されるリソースの種類) のリソースを処理するように更新する必要があります。

MVC では依然として AuthorizationFilterContext リソースが使用されるため、アプリがエンドポイント ルーティングの承認と共に MVC 承認フィルターを使用する場合は、両方の種類のリソースを処理する必要があります。

SignalR

SignalR ハブのマッピングは、UseEndpoints の内部で行われるようになりました。

各ハブを MapHub でマップします。 以前のバージョンと同様、各ハブが明示的に一覧表示されます。

次の例では、ChatHubSignalR ハブのサポートが追加されています。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>();
    });
}

クライアントからのメッセージ サイズの制限を制御するための新しいオプションがあります。 たとえば、Startup.ConfigureServices では次のようにします。

services.AddSignalR(hubOptions =>
{
    hubOptions.MaximumReceiveMessageSize = 32768;
});

ASP.NET Core 2.2 では、TransportMaxBufferSize を設定して、メッセージの最大サイズを効果的に制御できました。 ASP.NET Core 3.0 では、このオプションによって、バックプレッシャが観測される前に、最大サイズのみが制御されるようになりました。

共有フレームワーク内の SignalR アセンブリ

ASP.NET Core の SignalR サーバー側アセンブリが .NET Core SDK と共にインストールされるようになりました。 詳細については、このドキュメントの「古いパッケージ参照を削除する」を参照してください。

MVC コントローラー

コントローラーのマッピングは、UseEndpoints の内部で行われるようになりました。

アプリが属性ルーティングを使用する場合、MapControllers を追加します。 ルーティングには ASP.NET Core 3.0 以降の多くのフレームワークのサポートが含まれているため、属性ルーティング コントローラーの追加はオプトインになります。

次の部分を探します。

  • MapControllerRoute を含む MapRoute
  • MapAreaControllerRoute を含む MapAreaRoute

現在、ルーティングには MVC 以外のサポートが含まれているため、これらのメソッドが何を実行するかを明確に示すために用語が変更されています。 MapControllerRoute/MapAreaControllerRoute/MapDefaultControllerRoute などの規則ルートは、追加された順に適用されます。 まず、より具体的なルート (区分のルートなど) を配置します。

次に例を示します。

  • MapControllers は属性でルーティングされるコントローラーのサポートを追加します。
  • MapAreaControllerRoute は区分内のコントローラーの規則ルートを追加します。
  • MapControllerRoute はコントローラーの規則ルートを追加します。
public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapAreaControllerRoute(
            "admin",
            "admin",
            "Admin/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapControllerRoute(
            "default", "{controller=Home}/{action=Index}/{id?}");
    });
}

コントローラー アクション名からの Async サフィックスの削除

ASP.NET Core 3.0 では、ASP.NET Core MVC はコントローラー アクション名から Async サフィックスを削除します。 ルーティングとリンクの生成は両方とも、この新しい既定の影響を受けます。 次に例を示します。

public class ProductsController : Controller
{
    public async Task<IActionResult> ListAsync()
    {
        var model = await _dbContext.Products.ToListAsync();
        return View(model);
    }
}

ASP.NET Core 3.0 より前:

  • 上のアクションは、"Products/ListAsync" ルートでアクセスできました。

  • リンクの生成には、Async サフィックスを指定する必要がありました。 次に例を示します。

    <a asp-controller="Products" asp-action="ListAsync">List</a>
    

ASP.NET Core 3.0:

  • 上のアクションは、"Products/List" でアクセスできます。

  • リンクの生成には、Async サフィックスを指定する必要はありません。 次に例を示します。

    <a asp-controller="Products" asp-action="List">List</a>
    

この変更は、[ActionName] 属性を使用して指定された名前には影響しません。 既定の動作は、Startup.ConfigureServices の次のコードを使用して無効にすることができます。

services.AddMvc(options =>
    options.SuppressAsyncSuffixInActionNames = false);

リンクの生成にはいくつかの違いがあります (たとえば、Url.Link および同様の API を使用するなど)。 これには以下が含まれます。

  • 既定では、エンドポイント ルーティングを使用する場合、生成された URI のルート パラメーターの大文字と小文字の区別は必ずしも保持されません。 この動作は、IOutboundParameterTransformer インターフェイスを使用して制御できます。
  • 無効なルート (存在しないコントローラー/アクションまたはページ) の URI を生成すると、無効な URI を生成する代わりに、エンドポイント ルーティングの下に空の文字列が生成されます。
  • アンビエント値 (現在のコンテキストからのルート パラメーター) は、エンドポイント ルーティングによるリンクの生成で自動的には使用されません。 以前は、別のアクション (またはページ) へのリンクを生成する場合、指定されていないルート値は、"現在" のルートのアンビエント値から推論されます。 エンドポイント ルーティングを使用する場合は、リンクの生成時にすべてのルート パラメーターを明示的に指定する必要があります。

Razor Pages

Razor Pages のマッピングは、UseEndpoints 内で実行されるようになりました。

アプリが Razor Pages を使用する場合、MapRazorPages を追加します。 エンドポイント ルーティングでは多くのフレームワークがサポートされているため、Razor Pages の追加はオプトインになりました。

次の Startup.Configure メソッドでは、MapRazorPages は Razor Pages のサポートを追加します。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

エンドポイント ルーティングなしで MVC を使用する

ASP.NET Core 3.0 で UseMvc または UseMvcWithDefaultRoute を介して MVC を使用するには、Startup.ConfigureServices 内で明示的にオプトインする必要があります。 初期化中に承認と CORS ミドルウェアに依存できるかどうかを MVC が確認する必要があるため、これが必要になります。 アプリがサポートされていない構成を使用しようとした場合に警告するアナライザーが用意されています。

アプリでレガシ IRouter サポートが必要とされる場合は、Startup.ConfigureServices で次のいずれかの方法を使用して、EnableEndpointRouting を無効にします。

services.AddMvc(options => options.EnableEndpointRouting = false);
services.AddControllers(options => options.EnableEndpointRouting = false);
services.AddControllersWithViews(options => options.EnableEndpointRouting = false);
services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);

正常性チェック

正常性チェックは、エンドポイント ルーティングでの "ルーターウェア" として使用できます。

エンドポイント ルーティングで正常性チェックを使用するには、MapHealthChecks を追加します。 MapHealthChecks メソッドでは、UseHealthChecks と同じ引数を受け入れます。 UseHealthChecks 上で MapHealthChecks を使用する利点は、承認を適用し、照合ポリシーをきめ細かく制御できる点にあります。

次の例では、/healthz での正常性チェック エンドポイントに対して MapHealthChecks が呼び出されます。

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions() { });
    });
}

HostBuilder が WebHostBuilder に置き換わる

ASP.NET Core 3.0 テンプレートでは汎用ホストが使用されます。 以前のバージョンでは Web ホストが使用されていました。 次のコードは、ASP.NET Core 3.0 テンプレートで生成される Program クラスを示したものです。

// requires using Microsoft.AspNetCore.Hosting;
// requires using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

次のコードは、ASP.NET Core 2.2 テンプレートで生成される Program クラスを示したものです。

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

IWebHostBuilder は 3.0 でもそのまま使用され、上のコード サンプルに示されている webBuilder の型です。 WebHostBuilder は今後のリリースでは非推奨となり、HostBuilder によって置き換えられる予定です。

WebHostBuilder から HostBuilder への最も重要な変更点は、依存関係の挿入 (DI) です。 HostBuilder を使用する場合は、Startup の コンストラクターに次のコードのみを挿入できます。

HostBuilder DI 制約では、

  • DI コンテナーを 1 回だけビルドできます。
  • シングルトンの複数インスタンスの解決など、結果として発生するオブジェクトの有効期間の問題を回避します。

詳細については、「ASP.NET Core 3 でのスタートアップ サービスの挿入の回避」を参照してください。

AddAuthorization が別のアセンブリに移動された

ASP.NET Core 2.2 以下では、"Microsoft.AspNetCore.Authorization.dll" の AddAuthorization メソッドは、

  • AddAuthorizationCore に名前が変更されました。
  • "Microsoft.AspNetCore.Authorization.Policy" に移動されました。

"Microsoft.AspNetCore.Authorization.dll" と "Microsoft.AspNetCore.Authorization.Policy.dll" の両方を使用しているアプリには影響しません。

"Microsoft.AspNetCore.Authorization.Policy.dll" を使用していないアプリは、次のいずれかを実行する必要があります。

  • "Microsoft.AspNetCore.Authorization.Policy" に参照を追加します。 このアプローチはほとんどのアプリで機能し、必要なのはそれだけです。
  • AddAuthorizationCore を使用するように切り替えます。

詳細については、「AddAuthorization(o =>) オーバーロード破壊的変更が異なるアセンブリにも存続する #386」を参照してください。

Identity UI

ASP.NET Core 3.0 の Identity UI の更新によって、

  • Microsoft.AspNetCore.Identity.UI へのパッケージ参照が追加されます。
  • Razor Pages を使用しないアプリでは、MapRazorPages を呼び出す必要があります。 このドキュメントの「Razor Pages」を参照してください。
  • Bootstrap 4 が既定の UI フレームワークです。 IdentityUIFrameworkVersion プロジェクト プロパティを設定して、既定値を変更します。 詳細については、こちらの GitHub のお知らせを参照してください

SignalR

SignalR JavaScript クライアントは @aspnet/signalr から @microsoft/signalr に変更されました。 この変更に対応するには、package.json ファイル、require ステートメント、および ECMAScript import ステートメント内の参照を変更します。

System.Text.Json は既定のプロトコル

System.Text.Json は、クライアントとサーバーの両方で使用される既定のハブ プロトコルになりました。

Startup.ConfigureServices では、AddJsonProtocol を呼び出してシリアライザー オプションを設定します。

サーバー:

services.AddSignalR(...)
        .AddJsonProtocol(options =>
        {
            options.PayloadSerializerOptions.WriteIndented = false;
        })

クライアント:

new HubConnectionBuilder()
    .WithUrl("/chathub")
    .AddJsonProtocol(options =>
    {
        options.PayloadSerializerOptions.WriteIndented = false;
    })
    .Build();

Newtonsoft.Json に切り替える

System.Text.Json でサポートされていない Newtonsoft.Json の機能を使用している場合は、Newtonsoft.Json に戻すことができます。 前述の「ASP.NET Core 3.0 SignalR プロジェクトで Newtonsoft.Json を使用する」を参照してください。

Redis 分散キャッシュ

Microsoft.Extensions.Caching.Redis パッケージは、ASP.NET Core 3.0 以降のアプリでは使用できません。 パッケージ参照を Microsoft.Extensions.Caching.StackExchangeRedis に置き換えてください。 詳細については、「ASP.NET Core の分散キャッシュ」を参照してください。

ランタイム コンパイルをオプトインする

ASP.NET Core 3.0 以前では、ビューのランタイム コンパイルはフレームワークの暗黙的な機能でした。 ランタイム コンパイルは、ビューのビルド時コンパイルを補完します。 これにより、ファイルが変更されたときに、アプリ全体をリビルドすることなく、フレームワークで Razor ビューとページ (.cshtml ファイル) をコンパイルできます。 この機能は、IDE で簡単な編集を行い、ブラウザーを更新して変更を表示するシナリオをサポートしています。

ASP.NET Core 3.0 では、ランタイム コンパイルはオプトイン シナリオです。 ビルド時コンパイルは、既定で有効になっているビュー コンパイルの唯一のメカニズムです。 ランタイムは、.cshtml ファイルへの変更を検出したときに、Visual Studio または Visual Studio Code の dotnet-watch に依存して、プロジェクトをリビルドします。 Visual Studio で、実行 (Ctrl+F5) されているものの、デバッグ (F5) されていないプロジェクトの .cs.cshtml、または .razor ファイルへ変更が行われると、プロジェクトの再コンパイルがトリガーされます。

ASP.NET Core 3.0 プロジェクトでのランタイム コンパイルを有効にするには、

  1. Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation NuGet パッケージをインストールします。

  2. AddRazorRuntimeCompilation を呼び出すように Startup.ConfigureServices を更新します。

    ASP.NET Core MVC では、次のコードを使用します。

    services.AddControllersWithViews()
        .AddRazorRuntimeCompilation(...);
    

    ASP.NET Core Razor Pages では、次のコードを使用します。

    services.AddRazorPages()
        .AddRazorRuntimeCompilation(...);
    

https://github.com/aspnet/samples/tree/main/samples/aspnetcore/mvc/runtimecompilation のサンプルは、開発環境において条件付きでランタイム コンパイルを有効にする例を示しています。

Razor ファイルのコンパイルの詳細については、「ASP.NET Core での Razor ファイルのコンパイル」を参照してください。

マルチターゲットを介したライブラリの移行

ライブラリでは、多くの場合、複数のバージョンの ASP.NET Core をサポートする必要があります。 ASP.NET Core の以前のバージョンに対してコンパイルされたライブラリの多くは、問題なく動作し続けます。 次の条件では、アプリをクロスコンパイルする必要があります。

  • ライブラリがバイナリの破壊的変更がある機能に依存している。
  • ライブラリで ASP.NET Core 3.0 の新しい機能を利用したいと思っている。

次に例を示します。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
  </ItemGroup>
</Project>

3.0 ASP.NET Core 固有の API を有効にするには、#ifdefs を使用します。

var webRootFileProvider =
#if NETCOREAPP3_0
    GetRequiredService<IWebHostEnvironment>().WebRootFileProvider;
#elif NETSTANDARD2_0
    GetRequiredService<IHostingEnvironment>().WebRootFileProvider;
#else
#error unknown target framework
#endif

クラス ライブラリで ASP.NET Core API を使用する方法の詳細については、「クラス ライブラリで ASP.NET Core API を使用する」を参照してください。

その他の変更

.NET Core 3.0 以降の検証システムでは null 非許容型のパラメーターまたはバインド プロパティは [Required] 属性を持つものとして処理されます。 詳細については、[Required] 属性に関する記事を参照してください。

公開

プロジェクト ディレクトリで bin フォルダーと obj フォルダーを削除します。

TestServer

汎用ホストTestServer を直接使用しないアプリでは、ConfigureWebHostIWebHostBuilderTestServer を作成します。

[Fact]
public async Task GenericCreateAndStartHost_GetTestServer()
{
    using var host = await new HostBuilder()
        .ConfigureWebHost(webBuilder =>
        {
            webBuilder
                .UseTestServer()
                .Configure(app => { });
        })
    .StartAsync();

    var response = await host.GetTestServer().CreateClient().GetAsync("/");

    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

API の破壊的変更

以下の破壊的変更について確認してください。

キャッチオール パラメーターを使用したエンドポイント ルーティング

警告

ルーティングでバグが原因で、キャッチオール パラメーターがルートと正しく一致しない可能性があります。 このバグの影響を受けるアプリには、次の特性があります。

  • キャッチオール ルート (たとえば、{**slug}")
  • キャッチオール ルートが、一致すべき要求と一致しません。
  • 他のルートを削除すると、キャッチオール ルートが機能し始めます。

このバグが発生するケースの例については、GitHub のバグ 18677 および 16579 を参照してください。

このバグのオプトイン修正は .NET Core 3.1.301 SDK 以降に含まれています。 次のコードにより、このバグを修正する内部スイッチが設定されます。

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Azure App Service での .NET Core 3.0

Azure App Service への .NET Core のロールアウトが完了しました。 .NET Core 3.0 は、すべての Azure App Service データセンターで利用できます。

ASP.NET Core モジュール (ANCM)

Visual Studio のインストール時に ASP.NET Core モジュール (ANCM) が選択されたコンポーネントではなかった場合、または ANCM の以前のバージョンがシステムにインストールされていた場合は、最新の .NET Core ホスティング バンドル インストーラー (直接ダウンロード) をダウンロードし、インストーラーを実行します。 詳細については、「ホスティング バンドル」を参照してください。