misc.log

日常茶飯事とお仕事と

WCFサービスをDLL無しで配置、稼働させる

WCFで作成したRESTサービスを、DLLとしてまとめるのではなく、ソースのままWebサーバー(IIS)に配置する方法を調べていたのですが、なんか上手くいったっぽいのでメモ。大筋は職場の人が組み立ててくれた手順に従っての作業だったのですが、最後の最後、その人のサンプルではなく、自分たちで作ったものが上手くいかなかったので確認しました。

ビルドしたDLLでなくソースファイルのままで配置する

おおまかには以下の条件を満たせばOKです。

  • IISでアプリケーションとして設定した物理フォルダ下に「App_Code」フォルダを作る。
  • App_Codeフォルダ下に、C#VB.NETのソースを全部置く(ココでポイントとなるのは、*.svcファイルのビハインドコードもApp_Codeの下に置くということ)。
  • svcファイルに記載されているビハインドコードファイル名に「~/App_Code/」をつける(要するにビハインドコードへのリンクを更新するってこと)。もしかしたらこれはVisual Studioがやってくれるかもしれませんが……。

そんだけです。

やってはいけないこと

binフォルダに拡張子、ファイル名を変えただけのDLLが残っていると動きません。動かない原因はこれでした。App_Codeにソースを移してから、binフォルダのDLLを消すのが怖かったので「RestTest1.dll_」のように、末尾にアンダースコアをつけてDLLとして認識しないようにしていたのです。これが駄目だったみたい。

web.configのsystem.webタグの中に下記の設定を行い、Webサーバー上からIEでページを開いてエラー出力を確認してみました。

<customErrors mode="Off" />

すると……

ファイルまたはアセンブリ 'RestTest1.dll_'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。 
  説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。 

 例外の詳細: System.IO.FileNotFoundException: ファイルまたはアセンブリ 'RestTest1.dll_'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。

ソース エラー: 
現在の Web 要求の実行中にハンドルされていない例外が生成されました。障害の原因および発生場所に関する情報については、下の例外スタック トレースを使って確認できます。  

アセンブリ読み込みトレース: 以下の情報は、アセンブリ 'RestTest1.dll_' を読み込めなかった原因を調べるのに役立ちます。

警告: アセンブリ バインドのログ記録がオフにされています。
アセンブリ バインドのエラー ログを有効にするには、レジストリ値 [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) を 1 に設定してください。
注意: アセンブリ バインドのエラー ログに関連するパフォーマンス ペナルティがあります。
この機能をオフにするには、レジストリ値 [HKLM\Software\Microsoft\Fusion!EnableLog] を削除します。
 
スタック トレース: 
[FileNotFoundException: ファイルまたはアセンブリ 'RestTest1.dll_'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。]
   System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) +0
   System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +437
   System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +172
   System.Reflection.Assembly.Load(String assemblyString) +35
   System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +190

えっ?どういうこと??
ファイル「RestTest1.dll_」は確かに存在するのに読めていないと。ひょっとして、でもこれを消すときちんと動く。ちょっとよくわかりませんが……とりあえず、binフォルダに余計なモノを置いておくなということですね。

別に気にする必要無いこと

  • Visual Studio 2008と.NET Framework 3.5でしか試していないのですが、WCFのRESTサービスを作る際のプロジェクトファイルタイプは、プロジェクトの新規作成から[Visual C#]→[Web]→[WCFサービスアプリケーション]を選択しました。別にASP.NET Webアプリとかでなくてもできましたよ。
  • web.configの設定は特に変える必要なかった。

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)