xin9le.net

Microsoft の製品/技術が大好きな Microsoft MVP な管理人の技術ブログです。

SDK Style の csproj で ASP.NET (.NET Framework) を動かす

世の中は .NET 6 RC1 がリリースされ、.NET 6 (LTS) の時代がもうすぐそこまで来ています。が、現実はそんなに甘くない!.NET Framework 4.8 + ASP.NET MVC 5 で頑張っている人もいるんです!ただ、一度でも .NET Core 時代の SDK Style の .csproj (新形式) という甘い蜜を吸ってしまうと .NET Framework の .csproj (旧形式) はかなり厳しく感じます。むしろその一点だけでも .NET Framework を敬遠するレベル。特にどの辺りが嫌いかと言うと、

  • NuGet Package の管理が煩雑で、どの dll と依存関係にあるのかが全然分からない
  • .cs ファイルひとつ追加するだけでも .csproj にタグが 1 行増える
  • 多人数開発している際に .csproj がコンフリクトすることがちょくちょくある

などです。SDK Style の .csproj はこういった部分が解決されていて大変スッキリします。昨今は特に Web 開発をすることが多いので ASP.NET + SDK Style .csproj の組み合わせで開発できるようにしておくと何かと平和そう。ということで、今回はそんなアナタ (= 僕自身) のために SDK Style 版の ASP.NET プロジェクトの作り方を書き残します。

書き換え手順

備忘録ということで Step-by-step で作業メモを残します。でき上がりのサンプルプロジェクトは GitHub に Push しておいたので、そちらも併せてご参照ください。

今回は ASP.NET MVC 5 のみを取り扱いますが、一部読み替えれば WebForms / Web API / WebPages / SignalR などでも使えるのではないかと思います。

Step.1 : ASP.NET MVC 5 のプロジェクトを作成

まず、Visual Studio で .NET Framework の ASP.NET Web アプリケーションのプロジェクトを作成します。Wizard をポチポチっとするだけなので簡単です。

f:id:xin9le:20210921170350p:plain

f:id:xin9le:20210921170532p:plain

f:id:xin9le:20210921170905p:plain

親の顔より見た構造のプロジェクトが出来上がりました。.csproj を見てみると、複雑でイヤーな感じの旧形式の XML が見えます。ここから SDK Style の .csproj に書き換えていきましょう。

f:id:xin9le:20210921171401p:plain

Step.2 : .csproj を SDK Style に書き換える

.csproj をテキストエディタで開き、以下のように書き換えましょう。あのクソ長い XML がたったこれだけになります!

<Project Sdk="MSBuild.SDK.SystemWeb/4.0.50">

    <PropertyGroup>
        <TargetFramework>net48</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <!-- 必須 -->
        <PackageReference Include="Microsoft.AspNet.Mvc" Version="5.2.7" />
        <PackageReference Include="Microsoft.AspNet.Web.Optimization" Version="1.1.3" />
        <!-- 依存関係パッケージの最新化 -->
        <PackageReference Include="Antlr" Version="3.5.0.2" />
        <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
        <PackageReference Include="WebGrease" Version="1.6.0" />
    </ItemGroup>

    <ItemGroup>
        <Reference Include="Microsoft.CSharp" />
        <Reference Include="System.Web" />
    </ItemGroup>

</Project>

特に重要なのが 1 行目の <Project Sdk="MSBuild.SDK.SystemWeb/4.0.50"> の部分で、System.Web を利用した IIS 向けアプリケーションビルドをしてくれるようになります。細かいことは気にせず、これを使いましょう。

Step.3 : 不要なファイルを削除

SDK Style にすることで不要になる以下のファイルを削除しましょう。

  • \Properties\AssemblyInfo.cs
  • packages.config

f:id:xin9le:20210921182459p:plain

Step.4 : Assembly Binding のバージョン調整

参照しているアセンブリと Web.config に指定されている Assembly Binding 等のバージョン不一致を調整します。これは直接的には SDK Style 化には関係がないことですが、せっかくなので NuGet Package を最新化しておきましょう。つまりオマケです。

<dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
</dependentAssembly>

Step.5 : DotNetCompilerPlatform のバージョン調整

最後に Microsoft.CodeDom.Providers.DotNetCompilerPlatform のバージョンを揃えます。今回だと 3.6.0 の NuGet Package を参照することになるので、該当箇所を 3.6.0.0 にしましょう。これをしないと実行時にエラーになってしまうので、とっても大事!

<system.codedom>
    <compilers>
        <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
        <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
</system.codedom>

できあがり!

以上の 5 step が済んだら以下のようなプロジェクト構成になっているかと思います。特にアセンブリの依存関係部分がスッキリしたのではないでしょうか。

f:id:xin9le:20210921225908p:plain

では最後にデバッグ実行して動作確認をしてみましょう。IIS Express が立ち上がり、これまた親の顔より見た ASP.NET MVC 5 テンプレートの画面が立ち上がるはずです。

f:id:xin9le:20210921183752p:plain

注意点

ここまで来て「最高じゃないか!」と思いたいところですが、実は盛大な落とし穴があります。dotnet publish や Visual Studio の 発行 が .NET Framework の .csproj と同じようには挙動しません...!なんなら全然ダメダメで頭を抱えるレベル。たとえば

  • dotnet publish で bin フォルダの中身のみ出力される
  • web.config が Debug / Release で合成されない

などなど、Production 環境に乗せるにはかなり致命的なものが多いです。ビルド環境を整えようと思ったら華麗なる (?) CI 芸が必要になりそうというか、その部分さえクリアできれば使い物になりそうな予感はします。まさに「あともう一歩」というところでしょうか。