QA@IT

ASP.NETで自作DLLをどこからでも使用できる用にするには?

6223 PV

こんにちは、お世話になります。

例えば、下記のような書き方をWebのルートのWeb.configで指定すると、ルート配下のアプリケーションディレクトリ内でも使用できます。このような使い方ができる自作DLLを作り、Web.configに設定して使いたいのですが、「構成にエラーがあります。 サーバーでアプリケーション エラーが発生しました。このアプリケーションの現在のカスタム エラー設定では、セキュリティ上の理由により、アプリケーション エラーの詳細をリモート表示できません。ただし、ローカル サーバー コンピューターで実行されているブラウザーで表示することはできます。」と言うエラーが発生してうまく動きません。

<compilation defaultLanguage="c#" targetFramework="4.5">
  <assemblies>
    <add assembly="Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
  </assemblies>
</compilation>

上記のようにして設定して動かしたいので、snコマンドを使い公開キートークンを調べ、環境変数のpath内にパスを通し、下記のような
書き方をしましたがうまくいきませんでした。

DLLファイル名は、TEST.sample.DLL (アセンブリ署名は組み込み済み)です。
使われているnamespace: TEST.sample や TEST.sample.Web や TEST.sample.DATA があります。

<compilation defaultLanguage="c#" targetFramework="4.5">
  <assemblies>
    <add assembly="TEST.sample, Version=1.0.1.0, Culture=neutral, PublicKeyToken=12345Fabc1aa053a" />
  </assemblies>
</compilation>

DLLをコンパイルした端末とWebサーバーは違い、Webサイト側で下記の通りコンパイルする指定で動いています。

<pages compilationMode="Always" controlRenderingCompatibilityVersion="4.5"/>

どんな作業が足りないのでしょうか?
そもそも、DLLを普通のクラスで作成している事に原因があるのでしょうか?

皆さん、解決方法や問題点などを教えて頂けないでしょうか。

以上、宜しくお願い致します。

回答

そのエラーメッセージは customErrors 要素の mode 属性が RemoteOnly となっていて、リモートの PC からアクセスしているということだと思います。

そのエラーメッセージで書いてあるように、Web サーバーのブラウザでアクセスするか、mode 属性を Off にするとエラー詳細が表示されるはずですので、試してみてください。

customErrors 要素 (ASP.NET 設定スキーマ)
https://msdn.microsoft.com/ja-jp/library/vstudio/h0hfz6fc(v=vs.100).aspx

自作 .dll というのが何だか分かりませんが、何にせよ質問者さんがそれを作って、複数の Web アプリケーションで共通に使いたいということであれば、Web サーバーの GAC に置くほかないと思います。

グローバル アセンブリ キャッシュ
https://msdn.microsoft.com/ja-jp/library/yf1d93sz(v=vs.100).aspx

ただし GAC に置くには厳密名をつけなければなりません。

マネージ アプリケーションに対する厳密な名前による署名
https://msdn.microsoft.com/ja-jp/library/vstudio/h4fa028b(v=vs.110).aspx

厳密な名前付きアセンブリ
http://surferonwww.info/BlogEngine/post/2011/09/13/Strong-named-assembly.aspx

.dll を販売するソフトウェア会社でもない限り、そこまでやる必要はないと思います。共通に使うということはできませんが、Bin フォルダに置くことを検討してください。

ASP.NET Web サイト内の共有コード フォルダ
https://msdn.microsoft.com/ja-jp/library/t990ks23(v=VS.100).aspx

なお、GAC と Bin フォルダの両方に .dll を配置した場合は、以下のような注意が必要です。

ASP.net assembly loading from GAC or Bin
http://blogs.msdn.com/b/pranav_rastogi/archive/2010/10/18/asp-net-assembly-loading-from-gac-or-bin.aspx

編集 履歴 (0)

すでに書かれていますが、基本的にはDLLを共有するにはGACに置く必要があります。
※codebaseを明示する方法もありますがASP.NETではちょっと話がややこしくなります。

で、自作DLLをGACに置くことは、たいていの場合あまり現実的なメリットはありません。
単純に、アプリケーションごとにbinフォルダにコピー配置することをお勧めします。

編集 履歴 (0)

「構成にエラーがあります。 サーバーでアプリケーション エラーが発生しました。・・・」
は、セキュリティ上の理由で外部からのアクセスにはエラーメッセージを表示しないようになっているため表示されています。

隠されているエラーの詳細を表示したいのであれば、エラーメッセージをもう少し読み進めると
リモート コンピュータで表示できるようにする方法が書いてあると思いますので
それに従ってください
(ただしセキュリティ上、あなた以外のリモートコンピューターからエラーメッセージが見られえては困る場合は設定しないほうがいいでしょう)


公開鍵に指定している 12345Fabc1aa053a は適当に編集したものですよね?

署名まで終わっているのであれば、GACに登録すれば一先ず目的は達成できそうな気はします。

方法 : グローバル アセンブリ キャッシュにアセンブリをインストールする

ただしGACもなんでもかんでも登録していくと管理が大変になるので、codebaseとの併用なども検討してみてください。

codeBase 要素

以下の記事の最後のweb.configが具体例として参考になるかもしれません。

https://msdn.microsoft.com/ja-jp/library/dd255412.aspx

内容はそれを説明するものではありませんが、web.configの内容は
compilationで使うMicrosoft.VisualStudio.Enterprise.ASPNetHelper.dllのために
assemblyBinding 内でcodebaseを使用しています。

アセンブリのロードについては、以下に説明があります。

ランタイムがアセンブリを検索する方法

なお、DEVPATHという指定方法も出てきますが、これは開発時に強制的に読み込ませたい場合にのみ使うものであり、
リリース時には含むべきではありません。
(置いただけでGACよりも優先されるので予期せぬ問題が発生する場合があります。)

編集 履歴 (0)

お世話になります。

皆さんのおかげで問題解決致しました。(本件クローズ致します)

結局、GACの登録作業をチャンと理解していなかった点と、GACで登録していたタイミングでも
web.configでのバージョン指定が違っていた事が原因でした。

[assembly: AssemblyVersion("1.0.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

GACの登録が初めてで理解しきれていないタイミングにGACの登録処理を行い、上記のような設定で
コンパイルした自作DLLのプロパティーに書かれているバージョンを元にweb.configのバージョン
指定を1.0.0.0としてしまった事により、動かないと言う深みにハマッタ感があります。

解決はできました。
1つはGACに登録し、複数のWebアプリケーションで使用。
1つはGACに登録し、Webのルート直下のweb.config内でHTTPModuleとして指定を更に行なって
使用しています。

(投稿時間順)
flied_onionさん、SurferOnWwwさん、nachaさん、ありがとうございました。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。