質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

ASP.NET MVCプロジェクトから別のDLLの設定ファイルの値を取得する方法について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 345

yukibeatles

score 11

前提・実現したいこと

ASP.NET MVCプロジェクトから、C#クラスライブラリの設定ファイルの値を取得したいと考えています。

発生している問題・エラーメッセージ

//例外発生時のエラーメッセージは以下の通りです。
'DLLの該当名前空間.該当クラス' のタイプ初期化子が例外をスローしました。

//InnerExceptionは以下の通りです。
System.Configuration.ConfigurationException
"現在の構成システムでは、ユーザーによってスコープされた設定はサポートされません。"

該当のソースコード

呼び出し側プログラム(ASP.NET MVC)
(呼び出し側プログラムで呼び出し先プログラムの参照設定は行っています。
また、実行は、ローカル環境(localhost)で該当アクションメソッドが実行されるページにアクセスすることで行っています。)

[HttpPost]
public ActionResult Test(TestData testData) {
   //前略

     //ここでエラー
     var result = LibraryA.ClassA.ValueA;

   //後略
}

呼び出し先プログラム(C# クラスライブラリ(.dll))

namespace LibraryA {
    public static class ClassA{
        //ValueAは設定ファイル(Settings.settingsファイル)内に定義(スコープはアプリケーション)
        public static string ValueA = Properties.Settings.Default.ValueAProp;
    }
}

設定ファイルの定義方法はこちらを参考にしました。

試したこと

・呼び出し側プログラムが、ASP.NET MVCではなく、C#コンソールアプリケーションであれば、呼び出すことが可能でした。
・呼び出し先プログラムのValueAに直接文字列を指定してやると、問題なく呼び出すことが可能でした。

開発環境

●環境
・統合環境:Visual Studio 2019

●プロジェクト
・使用言語:C#(.NET Framework 4.6.1)
・種別:ASP.NET MVC 5 Webアプリケーション

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2020/07/12 09:51 編集

    質問者さん、無言になってしまいましたが、私の回答欄に【追記2】を書きましたので、それに対するフィードバックをしてください。

    もし、ギブアップしたなどでこのスレッドでの Q&A は不要になったということなら、それはそれで構いませんので、その旨書いてこのスレッドはクローズしてください。

    とにかく無言は NG です。

    キャンセル

  • yukibeatles

    2020/07/12 10:42

    返信が遅くなり申し訳ございません。
    上手くいかず現在検証しておりますので、少々お時間頂けますでしょうか。
    明日には回答予定です。
    遅くなり申し訳ございませんが、宜しくお願い致します。

    キャンセル

  • SurferOnWww

    2020/07/12 11:37

    返答をありがとうございます。お待ちします。

    キャンセル

回答 2

check解決した方法

0

呼び出し先のDLLの設定のすべての設定値(呼ぶ、呼ばないに関わらず)をアプリケーションスコープにする必要がありました。

呼び出し先のDLLの設定に1つでもユーザスコープの設定値が含まれていると、
ASP.NETアプリケーションでは呼ぶことができない様です。
理由に関しては、SurferOnWww 様が仰って頂いたように、ワーカープロセスからアクセスできないのだと思われます。
(このような意味でご回答頂いていたようであれば、申し訳ございません。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/13 15:57 編集

    MVC アプリが .dll を呼び出して、その .dll が使う .dll.config はどこにあったのですか? bin フォルダにあったにもかかわらず「1つでもユーザスコープの設定値が含まれている」とダメだったと言ってますか?

    キャンセル

  • 2020/07/13 16:21 編集

    ということは、私の回答の【追記】で、

    > 「スコープはユーザー」ということは、ユーザーの個人情報と思いますが、であればそれを構成ファイルに保存することは ASP.NET Web アプリでは不可能です。無理筋とかいうレベルではなくて、誰が何と言おうと 100% 不可能です。

    【追記2】には、

    > スコープはもちろん「アプリケーション」でなければなりません。

    ・・・と書いたことは見てもらえなかったということ?

    キャンセル

  • 2020/07/13 17:12

    .dll.configのファイルパスはいまだに不明です。
    MVCアプリのプロジェクトファイルをdllのファイル名で全検索しましたが、ありませんでした。
    MVC アプリ側の参照設定で、 .dllファイルは別のPATHを通したフォルダにコピーしたものの方を参照設定していますが、.dll.configはそのフォルダ内にもありません。
    2020/07/10 18:25の書き込みに示した、フォルダ内にもありませんでした。
    元のdllファイルのプロジェクトファイルのbinフォルダ内の .dll.configを参照しているのかと思い、一度削除してみましたが、それでも正しく設定値を取得できたので、ここでもありません。
    ただ、.dll.configに「1つでもユーザスコープの設定値が含まれている」とダメな様です。
    ユーザスコープの設定値を削除すると、正しく動作しました。

    キャンセル

  • 2020/07/13 17:18 編集

    >スコープはもちろん「アプリケーション」でなければなりません。
    に関して私は、呼び出し元のアプリケーションが、呼び出す先の呼び出す設定値のスコープのみが「アプリケーション」であればよいと認識していましたが、そうではなく、呼び出す/呼び出さないに関係なく、呼び出す先のすべての設定値のスコープを「アプリケーション」に変更する必要がありました。
    私の認識が甘く申し訳ございません。

    キャンセル

0

MVC プロジェクトとライブラリのプロジェクトの Visual Studio 上での構成がどうなっているか、参照設定はしているのか、MVC アプリの実行はどのようにしているのか、詳しいことが何も書いてないので、想像を膨らませてのレスですが・・・

ライブラリが使う構成ファイルがワーカープロセスからアクセスできない場所にあるからではないかと思います。問題の Properties.Settings.Default.ValueAProp を保存する構成ファイルはどこにあるのですか?

構成ファイルの保存場所の一般的な説明については以下の記事を見てください。

構成ファイルの保存場所
http://surferonwww.info/BlogEngine/post/2019/09/01/where-are-configuration-files.aspx

【追記】

今気が付きました。

//ValueAは設定ファイル内に定義(スコープはユーザー)

「スコープはユーザー」ということは、ユーザーの個人情報と思いますが、であればそれを構成ファイルに保存することは ASP.NET Web アプリでは不可能です。無理筋とかいうレベルではなくて、誰が何と言おうと 100% 不可能です。

ユーザー固有の情報ならユーザー認証を実装していると思いますが、ASP.NET Identity ならプロファイルを使ってはいかが?

【追記2】

下の 2020/07/11 11:01 の私のコメントで「後で、どのように試したかを質問欄に追記しておきます」と書きましたが、それを以下に追記します。

以下のようにすれば LibraryA の Settings.settings ファイルに設定した文字列は、MVC のコントローラーで、質問者さんと同じコードを使って取得できます。

MVC アプリのプロジェクトと同じソリューション内にクラスライブラリ LibraryA を追加し、下の画像の通り Settings.settings ファイルに文字列情報を追加。スコープはもちろん「アプリケーション」でなければなりません。Class1.cs の中の ClassA のコードは質問のコードをそのままコピペします。

イメージ説明

MVC プロジェクトで LibraryA を参照に追加します。

イメージ説明

そうすれば、ソリューションをビルドすると自動的に MVC プロジェクトの bin フォルダに LibraryA の .dll とともに .dll.config が コピーされます。その .dll.config に LibraryA の Settings.Settings ファイルに設定した文字列 "LibraryA の Settings.settings に設定した文字列" が含まれています。

イメージ説明

その後、コントローラで、質問者さんのコードの var result = LibraryA.ClassA.ValueA; を使って、bin フォルダにコピーされた .dll.config ファイルから目的の文字列を取得できます。

なので、最初の回答に書いた、

ライブラリが使う構成ファイルがワーカープロセスからアクセスできない場所にある

・・・は当たっていると思います。MVC プロジェクトの bin フォルダに .dll.config が無いのでは?

現状システムでは、サーバ側webアプリケーション(ASP.NET)とサーバ側常駐アプリケーション(C#コンソールアプリケーション)で、それらの橋渡しをする為に、同じ設定値を参照する必要があります。

「同じ設定値を参照」というのが、物理的に同じファイルから値を取得するということですと、それは無理っぽいです。.dll.config ファイルの配置場所は MVC アプリとコンソールアプリで別にならざるを得ないようですので。

同じ内容の .dll.config ファイルのコピーを 2 つ作って、MVC アプリとコンソールアプリに別々に配置するということは可能かもしれません。

そこは自分は未検証・未確認です。質問者さんの方で試して結果を教えてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/13 09:56

    > ご提案頂いた、同じ内容の .dll.config ファイルのコピーを 2 つ作って、MVC アプリとコンソールアプリに別々に配置する、ですと、管理が煩雑になってしまう、様に予想されましたので、別の方法を色々試してみました。

    提案しているわけではなくて、クラスライブラリの Settings.settings の情報を使うならそういう手段を取らざるを得ないと言っているだけです。

    私の提案は、2020/07/10 19:44 の私のコメントで書いたように「どういう目的で、何を保存したいのか、その目的に合った ASP.NET としての最適な方法を考えた方がよさそうです」です。

    例えば、DB を使うとか、DB が無理ならテキストファイルなり xml ファイルをコンソールアプリと共通に使い、MVC では Application_Start あたりで ApplicationState に情報を読み込んでそれを使うとか。

    > ASP.NET MVC側のソリューションには該当のDLLプロジェクトを追加せず、ASP.NET MVC側の参照にのみ該当のDLLを追加すると、

    ASP.NET ですからクラスライブラリの .dll は bin フォルダに配置されてないと動きません(GAC に配置しているなら話は別ですがそういうことはしてないと思ってます)。なので、MVC アプリでクラスライブラリが動いたのであれば bin フォルダに .dll は存在するはずです。

    ということは、.dll.config も bin フォルダに存在しないと読んでこれないはずです。先に紹介しましたが以下の記事を読んでください。

    構成ファイルの保存場所
    http://surferonwww.info/BlogEngine/post/2019/09/01/where-are-configuration-files.aspx

    その記事に書きましたが、構成ファイルのファイルパスは ConfigurationManager.OpenExeConfiguration メソッド で Configuration オブジェクトを取得し、その FilePath プロパティを使って取得できますので試してみてはいかがですか?

    キャンセル

  • 2020/07/13 10:31

    引き続きご回答ありがとうございます。
    要点を理解できておらず申し訳ございません。

    対応方法としては、共有可能なxmlファイルが用途として合っていると考えられますので、設定ファイルで対応できないようであれば、xmlファイルで対応しようかと考えております。
    他アプリケーションも設定ファイルで管理しており、極力設計思想を合わせたいので、勉強の意味も込め、もう少し設定ファイルで挑戦してみようと思っております。

    >ASP.NET ですからクラスライブラリの .dll は bin フォルダに配置されてないと動きません(GAC に配置しているなら話は別ですがそういうことはしてないと思ってます)。なので、MVC アプリでクラスライブラリが動いたのであれば bin フォルダに .dll は存在するはずです。

    仰る通りGACには配置しておりません。
    binフォルダ内に .dllの .dll.config ファイルは存在しておりませんが、.dllファイル自体は存在しております。(参照で該当DLLのプロパティでローカルにコピーをTrueにしている為)

    現状確認している挙動から、
    ASP.NETアプリケーションからはdllファイル参照しているだけで、.dllの設定ファイルは.dllファイルからアクセスしているだけ、というのは考えられませんかね…?
    (サーバへのデプロイ前でローカル環境での確認ですが)

    またdll側の3構成ファイルのファイルパスは2020/07/10 18:25で記載した通りです。
    呼び出し元のアプリケーションからどの構成ファイルにアクセスが必要があるのか、もう少し確認してみます。

    キャンセル

  • 2020/07/13 10:42 編集

    > .dllの設定ファイルは.dllファイルからアクセスしているだけ、

    それはそうですが、.dll.config にアクセスするには、その .dll.config がどこにあるか知ってないとアクセスできません。当たり前ですが。.dll と同じフォルダにあるというのがお約束ですから、そこ以外にあっても見つけられないかと・・・

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る