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

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

ただいまの
回答率

90.43%

  • C#

    7979questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    2086questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • ASP.NET

    573questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • IIS

    193questions

    IIS(Internet Information Services)はマイクロソフト社によって開発されたwebサーバーです。Windows上で動作します。

  • セッション

    99questions

    Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

IIS 7.5 Session mode="StateServer" を利用すると、特定のSession変数が消失する。(Sessionそのものはある)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 95

M.Ochiai

score 8

前提

複数のWebアプリケーションにおいて、Sessionを共有して動作する環境を構築しています。
表記の通り、SessionStateのStateServer modeを利用しています。

Grid画面からのListファイル出力機能を実装時に以下の問題が発生しました。

実行したいこと

  • Grid画面で、Filterをかけた状態で、ファイル出力を行った場合、
    Gridと同じFilter条件で絞り込んだ Listをファイルに出力したい。

処理の概要

  • 今回、Grid表示とファイル出力の間でFilter条件(Where句)を共有するため、Session変数を利用しています。
    画面でFilterをかけた際に Where句をSession変数に保持し、ファイル出力処理では、Session変数からWhere句を読み出して、出力時のQueryに付加します。

発生している問題

  • SessionStateを利用する環境では、いったん保存したWhere句のSession変数が、ファイル出力時に Nullになってしまう。

該当のソースコード

※すみません、検証用に記載したLog出力のみ記載します。

設定側

       Session["where"] = WhereQuery;
       Session["order"] = OrderByQuery;

       Logger.Info("XXXController.GetData()... WhereQuery ='" + Session["where"].ToString() + "' : OrderByQuery ='" + Session["order"].ToString() + "'");
       Logger.Info("XXXController.GetData()... SessionID : " + Session.SessionID);

取得側

     if (Session["where"] == null)
     {
          Logger.Info("XXXController.ExportData()... QueryInfo is Null!!");
          Logger.Info("XXXController.ExportData()... SessionID : " + Session.SessionID);
     } else 
     {
          Logger.Info("XXXController.ExportData()... WhereQuery ='" + Session["where"].ToString() + " : OrderByQuery ='" + Session["order"].ToString() + "'");
          Logger.Info("XXXController.ExportData()... SessionID : " + Session.SessionID);
     }

試したこと

InProcのDebug環境では、Nullにはならず、期待通りに動作します。
Logを埋め込み、確認しましたが、Setする側では、正しくSession保持していますが、利用する側では、Nullになってしまいます。
いろいろWeb検索もしましたが、むしろInProcではSessionが消えやすいとい情報はあるが、StateServerを利用すると消えるという情報は見つかりませんでした。
また、Sessionごと切れるのではなく、一部の変数のみが消えます。
(Login情報もSessionに保持していますが、こちらは健在です)
類似の事象、原因と思われる処理などなにかご存知の方、アドバイスお願いします。

補足情報(FW/ツールのバージョンなど)

  • 環境: Visual Studio 2015, .NET Framework 4.6.1 ASP.NET MVC 
  • 言語:C#
  • IIS 7.5
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • SurferOnWww

    2019/01/09 22:45

    ASP.NET のタグを付けてください。

    キャンセル

回答 2

check解決した方法

+3

SurferOnWwwさん、アドバイスありがとうございました。
不具合の原因が分かりました。

原因

今回の問題は、StateServerを用いた場合に、「特定」のセッション変数が消えてしまうというものでしたが、
その特定のセッション変数に値を設定(Add)している関数の最後で、

 Response.End();

を実行していると、直前にSessionに入れた変数が残らないもしくは消えるという現象でした。
InProcの場合には発生しませんでした。

Stack Overflowに類似情報を見つけました。
Response.End() causes session lost the first time session is used

対応

参考にならないかもしれませんが、恥ずかしながら今回は本来 Response.End()を利用する必要が無いメソッドでしたので、Response.End();削除することで、解決できました。
削除できない場合は、上記リンクが参考になるかもしれません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/10 15:49 編集

    (2019/1/11 追記:自分の環境で試してみましたが再現しません。なので、下に書いた「StateServer の場合は End メソッドで強制終了されてしまうとタイミングの問題で保持できない」は違うと思います。詳しくは追加した 2019/01/11 12:08 のコメントを見てください)

    情報の提供をありがとうございました。

    InProc の場合は Session["key”] = value; で即メモリに保持されるが、StateServer の場合は(多分、SQLServer の場合も)End メソッドで強制終了されてしまうとタイミングの問題で保持できない(こともある?)ということでしょうか。

    そうすると、End メソッドを呼び出す Response.Redirect("xxxx") または Response.Redirect("xxxx", ture) でも同じ問題がおきそうですね。

    ちなみに、.NET 4 以降の MSDN ライブラリの説明で、End メソッドの使用は非推奨になっています。理由は、End メソッドでスローされる ThreadAbortException がパフォーマンスに悪影響を及ぼすからだそうです。

    Stackoverflow の記事のケースは、Session_Start ハンドラを追加することで解決したと書いてあって、ちょっと違う話のような気がします。ちなみに、Session_Start ハンドラがあると、Session を使わなくても(空でも)常にセッション状態プロバイダーに保存されるという違いがあるそうですが、End メソッドとは関係なさそうに思えます。

    Session_Start ハンドラの影響について興味がおありでしたら以下の記事を読んでください。

    Session_Start ハンドラの影響
    http://surferonwww.info/BlogEngine/post/2014/07/26/session-state-management-and-session-start-event-handler-in-global-asax.aspx

    キャンセル

  • 2019/01/11 12:08

    自分が試した限り、「End メソッドで強制終了されてしまうとタイミングの問題で保持できない」ということはありませんでした。

    自分の環境(Windows 10 Pro 64-bit, IIS10. .NET 4.6.1 の ASP.NET Web Forms アプリ)で、Session を StateServer モードにして検証してみましたが、事前に Session クッキーが発行されていれば、Session にデータを保存して End しても、次の要求で必ず保存したデータを取得できます。

    質問者さんのケースでは、Session["where"] = WhereQuery; Session["order"] = OrderByQuery; で初めて Session にデータを保存した、即ち、その時点では Session クッキーは発行されていなかった(ブラウザは Session クッキーを持っていなかった)のではないでしょうか?

    具体的には、

    (1) 事前に Session クッキーが発行されていない状態で、Session にデータを保存した。

    (2) 保存した後 End したので処理がそこで中断されブラウザに応答は返ってこない。

    (3) ブラウザは Session クッキーを持っていないので、次の要求を出しても要求ヘッダには Session クッキーが含まれない。

    (4) 結果、Session に保存したデータが取得できなかった。

    ・・・ということではないのでしょうか?

    InProc でも必ず同じ問題が出るはずですが、質問者さんのケースで InProc では問題無かったのは、手順の違いか、もしくは、その環境では Global.asax に Session_Start ハンドラがあるなどで、事前に Session クッキーが発行されていたからではないかと思うのですが、いかがですか?

    キャンセル

+2

InProc で問題なく StateServer でダメということですと、シリアル化できないというのが思い当たります。そのあたりを調べてみてはいかがですか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/09 23:21

    早速のコメントありがとうございます。
    シリアル化も疑いましたが、違う様なんです。
    コードで示したようにセッションに入れてすぐに取り出した場合には参照できています。object型にしたりも試しましたが、変わりませんでした。
    エラーも出ていませんが、まだ疑う余地がありますか?

    その他、セッション変数にスコープや期限を指定する様な設定が有るのでしょうか?

    キャンセル

  • 2019/01/10 08:21

    ひょっとして、シリアル化の可否以前の問題で、StateServer モードにすると、いかなるデータも一切 Session に保持できない (取得すると null になる) ということですか?

    キャンセル

  • 2019/01/10 08:25

    そうではなくて、タイトルに書いてあるように「特定」のデータだけということなら、特定とそうでないものの違いは何ですか?

    キャンセル

  • 2019/01/10 09:05

    「特定」のデータだけです。
    違いが分からずにいたのですが、改めて言われて着目してみると、
    Session.Add してる場所(処理)が異なる点以外には違いが見当たりません。
    そう考えると、Addしている処理で何かやらかしている可能性がありますね。
    ありがとうございます。その辺りを調査してみます。

    キャンセル

  • 2019/01/10 10:43

    「特定」とそうでないデータもしくは操作の仕方の違いが明確になったら教えていただけると幸いです。

    キャンセル

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

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

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

  • C#

    7979questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    2086questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • ASP.NET

    573questions

    ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

  • IIS

    193questions

    IIS(Internet Information Services)はマイクロソフト社によって開発されたwebサーバーです。Windows上で動作します。

  • セッション

    99questions

    Sessionはクライアントがサーバに送ったすべてのリクエストのことを指します。

  • トップ
  • C#に関する質問
  • IIS 7.5 Session mode="StateServer" を利用すると、特定のSession変数が消失する。(Sessionそのものはある)