トップ回答者
仮想ディレクトリを含むASP.NETサイトをmsbuildでコンパイル

質問
-
仮想ディレクトリを含むASP.NETサイトをmsbuildでビルドがうまくいかず困っています。最終目標はJenkinsなどのツールでブラウザからワンクリックでのデプロイをすることなのでビルド時のエラーを0にしたいです。
とりあえず最小限で再現するソリューションを作成してGithubにアップいたしましので参考にしていただければと思います。
https://github.com/gomo/VirtualDirTest
まずbuild.csprojを使わずにVirtualDirTest.slnに対してビルドすると下記のようなエラーが出ます。
> C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild C:\Projects\VirtualDirTest\VirtualDirTest.sln Microsoft (R) Build Engine バージョン 4.6.1586.0 [Microsoft .NET Framework、バージョン 4.0.30319.42000] Copyright (C) Microsoft Corporation. All rights reserved. このソリューション内のプロジェクトを 1 度に 1 つずつビルドします。並行ビルドを有効にするには、"/m" スイッチを追加してください。 2017/04/14 22:19:21 にビルドを開始しました。 ノード 1 上のプロジェクト "C:\Projects\VirtualDirTest\VirtualDirTest.sln" (既定のターゲット)。 ValidateSolutionConfiguration: ソリューション構成 "Debug|Any CPU" をビルドしています。 プロジェクト "C:\Projects\VirtualDirTest\VirtualDirTest.sln" (1) は、ノード 1 上に "C:\Projects\VirtualDirTest\web_2_.metaproj" ( 2) をビルドしています (既定のターゲット)。 Build: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v /localhost_49680 -p web\ -u -f -d PrecompiledWeb\localhos t_49680\ /localhost_49680/Default.aspx(2): error ASPPARSE: ファイル '/localhost_49680/uc/WebUserControl.ascx' は存在しません。 [C:\Project s\VirtualDi rTest\web_2_.metaproj] /localhost_49680/Default.aspx(14): error ASPPARSE: 不明なサーバー タグ 'uc:Test' です。 [C:\Projects\VirtualDirTest\web_2_.metapr oj] プロジェクト "C:\Projects\VirtualDirTest\web_2_.metaproj" (既定のターゲット) のビルドが終了しました -- 失敗。 プロジェクト "C:\Projects\VirtualDirTest\VirtualDirTest.sln" (既定のターゲット) のビルドが終了しました -- 失敗。 ビルドに失敗しました。 "C:\Projects\VirtualDirTest\VirtualDirTest.sln" (既定のターゲット) (1) -> "C:\Projects\VirtualDirTest\web_2_.metaproj" (既定のターゲット) (2) -> (Build ターゲット) -> /localhost_49680/Default.aspx(2): error ASPPARSE: ファイル '/localhost_49680/uc/WebUserControl.ascx' は存在しません。 [C:\Proje cts\Virtual DirTest\web_2_.metaproj] /localhost_49680/Default.aspx(14): error ASPPARSE: 不明なサーバー タグ 'uc:Test' です。 [C:\Projects\VirtualDirTest\web_2_.meta proj] 0 個の警告 2 エラー 経過時間 00:00:01.25
msbuildから仮想ディレクトリが見えないからエラーになっているのでは?と想像し、色々検索してみて、MsBuildTasksをインストールしてWebDirectoryCreateを利用すればビルド時に仮想ディレクトリを作成することができるのでは?と思い試してみました。すると下記のようなエラーが。
> C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild C:\Projects\VirtualDirTest\build.csproj Microsoft (R) Build Engine バージョン 4.6.1586.0 [Microsoft .NET Framework、バージョン 4.0.30319.42000] Copyright (C) Microsoft Corporation. All rights reserved. 2017/04/14 22:18:21 にビルドを開始しました。 ノード 1 上のプロジェクト "C:\Projects\VirtualDirTest\build.csproj" (既定のターゲット)。 VirtualDirectory: Deleting virtual directory 'uc' on 'localhost:80'. C:\Projects\VirtualDirTest\build.csproj(21,5): error : 不明なエラー (0x80005000) プロジェクト "C:\Projects\VirtualDirTest\build.csproj" (既定のターゲット) のビルドが終了しました -- 失敗。 ビルドに失敗しました。 "C:\Projects\VirtualDirTest\build.csproj" (既定のターゲット) (1) -> (VirtualDirectory ターゲット) -> C:\Projects\VirtualDirTest\build.csproj(21,5): error : 不明なエラー (0x80005000) 0 個の警告 1 エラー 経過時間 00:00:00.34
仮想ディレクトリの変更をlocalhost:80に対して行ってるあたりが気にはなるのですが、エラーがざっくりした内容でこれ以上検索できずこの辺で行き詰まりました。なんか、違う方向に向かってるような気もするので、この辺のワードで調べればいいとか、そういうヒントでもいいのでいただけたら助かります。
回答
-
アプリケーションを跨がず、それぞれのアプリケーションの中で完結するのが最も基本的な考え方だとは思います。
例えばですが、共通利用したいものをNuGetパッケージにして配布したり、gitのsubmoduleやsubtreeなどの機能でリポジトリ上で共有したり……などといった手段を用いて、あくまで『参照はアプリケーション内で完結させる』ようにすることを検討してみるのはいかがでしょうか。
(各種非機能要件にもよるとは思いますが私であればまずはこのアプローチから検討すると思います)
きよくらならみ
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年4月18日 2:24
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年4月24日 2:04
すべての返信
-
レスありがとうございます。
状況を説明させていだだきます。
Windows10でローカル開発をしていて、公開しているサーバーはWindowsサーバー2014です。
作っているのはASP.NET Web Formsもウェブサイトです。先の質問で貼ったGithubのURLは、問題を再現するために新しいプロジェクトを作成したもので、実際には他の方が作った独自のクラスライブラリなどを含む結構大きめのサイト引き継いで機能追加やメンテナンスをしています。
サーバーの台数が増えてきたので、Jenkinsを使ってブラウザからポチッとデプロイできないか色々試していました。大方うまく入ったのですが、仮想ディレクトリにおいてあるユーザーコントロールを読み込んでるところが何箇所かあって、そこでエラーになってしまうので、その解消方法を探しています。
ちなみに、なぜ仮想ディレクトリにユーザーコントロールを置いているかというと、他のサイト(アプリケーション)でも使い回している汎用的なユーザーコントロールが置いてあるからです。ソースはGitで管理していますが、リポジトリも別になります。
現状はどのようにデプロイしているかというと、サーバーにログインし、サーバーでGithubから最新ソースをPULLします。その後、コマンドプロンプトでMSBuildでソリューションファイルをビルドしています。別のディレクトリに発行しているわけではなく、直接PULLしたslnをターゲットにビルドして、IISのドキュメントルートもそのクローンしたディレクトリに直接当たっています。
当然ですが、この時も同じように仮想ディレクトリでエラーが出るのですが、IISには仮想ディレクトリの設定がされているので、ページを表示するとエラーにはならず表示される状態です。
仮想ディレクトリを利用して汎用的なユーザーコントロールをアプリケーションを跨いでインクルードするのは間違いなのでしょうか?間違いだとすればどのようにするのが一般的なのでしょうか?ビルド前のフックなどを使ってコピーするのは可能な気がしました。
仮想ディレクトリと使うのがもし問題ない(一般的に行われる)のであるとすれば、ビルド時にファイルが見つからないエラーを出さないようにするにはどうすればいいでしょうか?
以上、長文ですいません。よろしくお願いします。
-
アプリケーションを跨がず、それぞれのアプリケーションの中で完結するのが最も基本的な考え方だとは思います。
例えばですが、共通利用したいものをNuGetパッケージにして配布したり、gitのsubmoduleやsubtreeなどの機能でリポジトリ上で共有したり……などといった手段を用いて、あくまで『参照はアプリケーション内で完結させる』ようにすることを検討してみるのはいかがでしょうか。
(各種非機能要件にもよるとは思いますが私であればまずはこのアプローチから検討すると思います)
きよくらならみ
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年4月18日 2:24
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年4月24日 2:04
-
レスありがとうございます。
> 例えばですが、共通利用したいものをNuGetパッケージにして配布したり、gitのsubmoduleやsubtreeなどの機能でリポジトリ上で共有したり……などといった手段を用いて、あくまで『参照はアプリケーション内で完結させる』ようにすることを検討してみるのはいかがでしょうか。
昨日ためしに仮想ディレクトリをやめてMSBuildのタスクを使って該当のユーザーコントロールのディレクトリをコピーしてビルドしするのを試してました。NuGetやgit submoduleの方がより自然ですね。ありがとうございます。検討してみます。