Skip to content

MS_MigrationToASPNETCore

nishi_74322014 edited this page Aug 12, 2026 · 1 revision

ASP.NET Coreへの移行

概要

※ 対象は、ASP.NET Core 2.0。

  • ASP.NET Core」のMVC6
    WebAPIへの移行ノウハウをサマリする。

  • 下記と異なり、新規作成したテンプレートに、
    UOC(User Own Coding)部分を移行する形になるため
    コンバージョン手順は書かない。

  • 従って、ココでは、ひたすら、ASP.NET
    ASP.NET Coreの差異について書いて行く。

    • ざっくり、B / D 層以外の、以下のような P 層の変更が多い。
      • System.Web による API 変更
      • 新しい DI による構成方法の変更
      • 要求処理パイプラインの変更
      • 認証周りの API の変更
      • , etc.
    • また、ASP.NET Coreのフレームワークは
      MVC6Razor Pagesで、
      主流が、MVC6になる。

移行メモ(本ページの前提年代): 本ページは
ASP.NET Core 2.0(2017年)時点の記述である。
骨格(脱 System.Web / DI / パイプライン / 認証 API)は
現在も変わらないが、周辺のツール(bower / Grunt 等)は
大きく入れ替わっている。各節に補足を付す。

選定基準

概要

以下に合致するケースに適合する。

  • Linux がサポートする、nginx(DNET_nginx.md) +
    Docker(DNET_Docker.md)などのクロスプラットフォームで、
    ハイパフォーマンスを実現するマイクロサービスなどの
    新しいアーキテクチャに対応させたい場合。

  • そのような中で、昔から使っている C# / VB などの言語、
    Visual Studioの開発環境を使用したい。

しかし、現在は IoT、クラウド、次世代のモバイルソリューションなど、
多くのシナリオの基礎になっているらしく、
既定で、ASP.NET Core を選択しても良いかもしれない。

補足(現在の判断は単純である): 執筆時は「選定基準」を検討する
余地があったが、現在は次のとおり選択肢が実質 1 つになっている。

現状
ASP.NET(.NET Framework) 新機能なし。.NET Framework 4.8 と共に据え置き
ASP.NET Core 新規開発はすべてこちら

検討すべきは「移行するか否か」ではなく、
いつ・どの範囲を移行するか」である。

事前準備

補足(移行の定石): 実務での順序は次のとおり。
下(ライブラリ)から上(UI)へ進めるのが鉄則である。

  1. クラス ライブラリを netstandard2.0 にする
    → .NET Framework 側からも参照でき、両方から使える状態になる。
  2. プロジェクト形式を SDK スタイルに変換する(try-convert)。
  3. UI(P 層)を新規テンプレートに載せ替える
    → ここは本ページの言うとおり、書き直しになる。
  4. 最後にライブラリを net8.0 に上げ、.NET Framework 依存を切る。

1 と 2 は既存アプリを動かしたまま進められるため、
リスクを小さく刻める。

フォルダ構成

依存関係

参照設定を行う。

  • パッケージ・マネージャ
    • NuGet
    • bower
    • npm
    • LibMan
  • SDK(アセンブリ参照 / プロジェクト参照)
  • アナライザー

Properties / launchSettings.json

  • 起動設定、構成管理ツール(MS_ConfigurationManagementTools.md)には登録されない。
  • Visual Studio の[デバッグ]タブには、ファイル編集の GUI がある。
  • 複数の起動設定を Command Line で切り替えることができる。

wwwroot

静的コンテンツを配置する。

その他のフォルダ

フォルダ 内容
Controllers MVC6*.cs or *.vb
Models MVC6*.cs or *.vb
Views MVC6*.cshtml or *.vbhtml
Pages Razor Pages*.cshtml or *.vbhtml

その他のファイル

Program

Web アプリケーションのエントリポイント

Startup

  • 経緯

    • .NET Framework のASP.NETでは、
      • OWINにより Startup がサポートされたが、
        Global.asax は生きていたので併用も可能だった。
    • これに対してASP.NET Coreでは、
      • Startup は、OWINに依存せず、Program.csMain 経由で
        読み込まれる。
      • このため、完全に、Global.asax から Startup に移行する必要がある。
  • 処理
    ミドルウェア / サービス / フレームワークを Startup クラスのメソッドで
    注入することにより、活用できるようになる。

    • 必要に応じて、ConfigureServices メソッドでミドルウェア / サービス /
      フレームワークを注入する。
    • Configure メソッドでアプリケーション、ミドルウェア / サービス /
      フレームワークの要求処理パイプラインを構成する。

補足(最新化:Startup.cs は無くなった): .NET 6 以降の
テンプレートは Minimal Hosting になり、
Startup.cs が廃され Program.cs 1 本に集約された。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();   // 旧 ConfigureServices

var app = builder.Build();
app.UseStaticFiles();                          // 旧 Configure
app.MapDefaultControllerRoute();
app.Run();

従来の Startup.cs 方式も引き続き動作するため、
移行時に慌てて書き換える必要はない。
ただし新しいドキュメント・サンプルはすべて上記の形なので、
読み替えができる必要はある。

appsettings.json

bundleconfig.json

  • BundleConfig.cs から bundleconfig.json に変更されている。
  • bundling and minification の結果は、wwwroot に保存される。
  • CDN フォールバックは ScriptTagHelperasp-fallback 系属性で実装できる。

パッケージ・マネージャの設定ファイル

  • package.json(npm)
  • bower.json.bowerrc(bower)
  • libman.json(LibMan)

パッケージ・マネージャ

NuGet

  • 言わずと知れた NuGet。
  • 現在は、ASP.NET Coreの既定のパッケージ・マネージャになっている。

bower

  • ブラウザで使用する CSS/JavaScript ライブラリはコチラから取得する。
  • Visual Studioとは、わりと上手く統合されているもよう。

npm

  • テンプレートから angular や react を選択すると NuGet に加え、
    npm が使える状態で初期化される。
  • パッケージ・マネージャの機能の範囲に限定すれば、
    Visual Studioと、上手く統合されているもよう。

LibMan

  • 軽量なクライアント側ライブラリ取得ツール
  • wwwroot/lib の復元のために利用できる。

補足(最新化:bower は廃止された): bower は 2017年に非推奨となり、
現在は使われていない

ASP.NET Coreのテンプレートからも削除済みである。

現在のクライアント側資産の管理は次のいずれかになる。

手段 向く場面
LibMan jQuery / Bootstrap を数個置くだけ。ビルド不要
npm + バンドラ(Vite / webpack) SPA・TypeScript を含む本格的なフロント
CDN 参照 最も軽い。オフライン要件が無い場合

元ページが「Open棟梁テンプレートでは bower を廃止し npm に一本化した」と
書いているのは、この流れを先取りした妥当な判断であった。

タスク・ランナー

Visual Studioでは、

  • BundlerMinifier.Core などが標準でサポートされている他、

  • Gulp と Grunt のタスク ランナーがサポートされている。

  • npm も、package.json で、タスク・ランナー的に使える。

    • ただし、タスク・ランナーの機能の範囲では、
      Visual Studioと、あまり上手く統合されていない。

補足(最新化): Grunt / Gulp / BundlerMinifier はいずれも
現在ほぼ使われていない

BundlerMinifier は 2023年にアーカイブされた。

現在は npm scripts + Vite(あるいは webpack / esbuild)で
ビルドし、成果物を wwwroot に出力する構成が標準である。
Visual Studio側も
SpaProxy / npm run build の呼び出しで統合できる。

構成

複数環境の構成

ASPNETCORE_ENVIRONMENT 環境変数を使用して複数の構成を初期化できる。

  • 環境名: Development / Staging / Production
  • 対象
    • launchSettings.json の設定
    • Startup クラス内での各種設定
    • EnvironmentTagHelper の利用

DIによる構成

  • ASP.NET Core における DI(MS_ASPNETCoreDI.md
  • ミドルウェアのインジェクション

ライブラリ

未分類のAPI

Request.IsAuthenticated が無い User.Identity.IsAuthenticated に置き換える
HttpNotFound / HttpStatusCodeResult が無い NotFound / StatusCode メソッドを利用する
OutputCache が無い ResponseCache を使うか、データキャッシュに実装しなおす

補足(よく詰まる非互換の追加): 上記以外で移行時に頻出するものを挙げる。

.NET Framework 版 ASP.NET Core
HttpContext.Current 廃止。DI で IHttpContextAccessor を注入
Server.MapPath() IWebHostEnvironment.ContentRootPath / WebRootPath
ConfigurationManager.AppSettings IConfiguration.NET configを参照)
System.Web.HttpUtility System.Net.WebUtility / Microsoft.AspNetCore.WebUtilities
Session["key"](任意のオブジェクト) HttpContext.Sessionbyte[] / string / int のみ。複雑な型は自前でシリアライズ)
Global.asaxApplication_Error 例外処理ミドルウェア(UseExceptionHandler
HTTP モジュール / ハンドラ ミドルウェア

HttpContext.Current に依存した静的ヘルパーが
ライブラリ層に潜り込んでいると移行コストが跳ね上がる。
事前に洗い出しておきたい最重要ポイントである。

ミドルウェア

サービス、フレームワークなどと呼ばれることもある。

認証

EF Core(MS_EntityFrameworkCore.md

非互換がある模様。

  • FindAsync メソッドが無い。
  • SqlQuery メソッドが無い。

移行メモ(最新化): 上記は EF Core 1.x 時点の話で、現在は解消している。

元ページ 現在
FindAsync が無い EF Core 1.1 以降で実装済み
SqlQuery が無い FromSqlRaw / FromSqlInterpolated、EF Core 7 以降は SqlQuery<T>

一方で、EF Core にはLazy Loading の既定無効
クライアント評価の禁止(EF Core 3.0 以降)など、
EF6 とは挙動が異なる点が残る。
特に後者は「EF6 では動いていた LINQ が実行時例外になる」
という形で表面化するため、移行時の要注意点である。

その他

エラー処理

開発者例外ページが非常に良くなっているようなのでこれを使わない手はない。

以下の例外画面を構成できる。

  • 開発者例外ページ(UseDeveloperExceptionPage
  • カスタム例外処理ページ(UseExceptionHandler
  • ステータス コード ページ(UseStatusCodePages

補足: 開発者例外ページは本番で有効にしてはならない
(スタック トレース・環境変数・接続文字列が露出する)。
テンプレートでは if (app.Environment.IsDevelopment())
囲われているので、これを外さないこと。

旧情報(1.0時代)

機能面

補足(Web Forms からの移行の現実解): 「移行は不可能」は
自動変換という意味では今も正しい
実務での選択肢は次の 3 つになる。

方針 内容
Blazor コンポーネント + イベント ドリブンで発想が最も近い。Microsoft も移行先として案内
ASP.NET Core MVC / Razor Pages へ 画面単位で素直なのは Razor Pages(1 画面 1 ファイル = Web Forms に近い)
据え置く .NET Framework 4.8 のまま維持。Windows のサポートが続く限り動く

「1 画面 1 Form」という Web Forms の構造は、
MVC よりも Razor Pages に対応させる方が自然である点は
見落とされやすい。

検討

旧資産に縛られている場合

旧資産に縛られている場合はなかなか移行できないと思う。

  • 例えば、SaaS 開発の方で ChartControl などを使っているが、
    ASP.NET Coreではソコまでの機能拡充がされる気配が
    今の所無いと思う。

  • Linux も必須の要件ではないし、ビジネス・アプリケーションの、
    Dynamics CRM(MS_Dynamics.md)では
    Web Forms (ASPX)が現役だったりする。

    と、個人的には(現段階では、まだ、)結構微妙と考えている。

旧資産から解放された場合

旧資産から解放された場合は、思い切ったシフトができると思う。

所感

  • ASP.NET Core(1.0)は、不安定で変更が多い。

  • 例えば、細かい話、ASP.NET Identity の PasswordHasher の実装が違う。
    既存データでウワモノ移行などでは、更に難易度が上がる気配も...。

  • このように、2017年12月 現在、ASP.NET Coreは、
    まだ安定しているとはいえないが、

    • 2017年8月、ASP.NET Core 2.0 が公開され、
    • ASP.NET MVC(MVC5)が、2015年2月以降、更新されていないので、

    今後、メインストリーム、新技術サポートが、
    MVC6に移っていく可能性がある。

補足(答え合わせ): 「メインストリームが MVC6 に移る」という予想は
完全に的中した
また「不安定で変更が多い」という当時の懸念も、
.NET 6 以降は LTS 中心の年次リリースに落ち着き、解消している。

PasswordHasher の非互換については、
ASP.NET Core Identity側に
互換モードPasswordHasherCompatibilityMode.IdentityV2)が
用意されており、既存のハッシュを検証しつつ
ログイン時に新形式へ段階的に移行できる。
移行時に泣かずに済む数少ない親切な仕組みである。

ASP.NET Core on .NET Core or .NET Framework

ASP.NET Coreのプロジェクト・テンプレートに、

  • ASP.NET Core Web Application (.NET Core)
  • ASP.NET Core Web Application (.NET Framework)

があったが、ASP.NET Core 2.0 時点から
サポートプラットフォームは .NET Core のみに絞られた。

移行メモ(正確な時期): 「2.0 時点で絞られた」は少し早い。
実際には ASP.NET Core 2.0 では両方サポートされ、
ASP.NET Core 3.0(2019年)で .NET Framework のサポートが終了
した。
ただし「.NET Framework を切る」という方針表明自体は
2.0 の頃に行われており、本ページの認識はその文脈である。

参考

microsoft.com

OSSコンソーシアム

その他


Tags: 移行, .NET開発, .NET Core, ASP.NET, ASP.NET MVC

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally