ASP.NETの任意のクラスからセッション変数にアクセスする方法は?


157

アプリケーションのApp_Codeフォルダーにクラスファイルを作成しました。セッション変数があります

Session["loginId"]

クラスでこのセッション変数にアクセスしたいのですが、次の行を書き込んでいるとエラーになります

Session["loginId"]

ASP.NET 2.0(C#)のapp_codeフォルダーに作成されたクラス内のセッション変数にアクセスする方法を誰かに教えてもらえますか

回答:


363

(完全性のために更新)
セッション変数には、任意のページまたはコントロールを使用Session["loginId"]して、任意のクラスから(たとえば、クラスライブラリ内から)、以下を使用してアクセスできます。System.Web.HttpContext.Current.Session["loginId"].

しかし、私の元の答えを読んでください...


私は常にASP.NETセッションのラッパークラスを使用して、セッション変数へのアクセスを簡略化しています。

public class MySession
{
    // private constructor
    private MySession()
    {
      Property1 = "default value";
    }

    // Gets the current session.
    public static MySession Current
    {
      get
      {
        MySession session =
          (MySession)HttpContext.Current.Session["__MySession__"];
        if (session == null)
        {
          session = new MySession();
          HttpContext.Current.Session["__MySession__"] = session;
        }
        return session;
      }
    }

    // **** add your session properties here, e.g like this:
    public string Property1 { get; set; }
    public DateTime MyDate { get; set; }
    public int LoginId { get; set; }
}

このクラスは、ASP.NETセッションに自身の1つのインスタンスを格納し、次のように、任意のクラスからタイプセーフな方法でセッションプロパティにアクセスできるようにします。

int loginId = MySession.Current.LoginId;

string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;

DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

このアプローチにはいくつかの利点があります。

  • それは多くの型キャストからあなたを救います
  • アプリケーション全体でハードコードされたセッションキーを使用する必要はありません(例:Session ["loginId"]
  • MySessionのプロパティにXMLドキュメントコメントを追加して、セッションアイテムを文書化できます。
  • セッション変数をデフォルト値で初期化できます(例:それらがnullではないことを保証します)

6
コードを記述する必要はありません。答えに示されているように使用してください。例: "public int LoginId {get; set;}"->これは自動プロパティと呼ばれます。
M4N 2009

4
.net 3.xを使用している場合は、私のコードに示すように自動プロパティを使用できます。.net 2.x / 1.xでは、これは使用できません。プロパティのゲッター/セッターを自分で実装する必要があります:private int _loginId; public int LoginId {get {return _loginId; }セット{_loginId = value; }}
M4N 2009年

2
私は私の問題の答えを得たと思います。私はいつもあなたの方法を使用しています。非常にクリーンで、すべてのセッション変数を1か所で維持するのは簡単です。@Martinさん、ありがとうございます。
Prashant

23
@ M4N、+ 1よりも少し感謝の気持ちを表すことができればと思います。これは、私のプロジェクトでセッション/キャッシュを扱う私のお気に入りの方法になっています。私のコードは、文字通り、あなたに感謝しています。
ブランドンブーン

4
@Kristopher 'Current'プロパティが静的である間、返されるMySessionのインスタンスはそうではないので、問題ありません。静的メソッドとプロパティは、この方法で安全に使用できます。
Darren

104

スレッドHttpContextを介してセッションにアクセスします:

HttpContext.Current.Session["loginId"]

この単純なステップを実行してくれたAnthonyに感謝します。
キングス

Anthonyに感謝+1、そのため
Owais Qureshi

ありがとう。名前空間を忘れてしまった:)
Anthony Horne 14年

私は、私が間違っているか、使用する適切な方法は何であり、私の質問のあなたの方法を使用しますが、問題を抱えている、あなたは私を説明することができ@AnthonyWJones stackoverflow.com/questions/45254279/...
アドナン

HttpSessionStateBaseに変換する場合:HttpSessionStateBase session = new HttpSessionStateWrapper(HttpContext.Current.Session); re:stackoverflow.com/questions/5447611/…–
sobelito

24

提案されたソリューションの問題は、アウトプロセスセッションストレージを使用している場合、SessionStateに組み込まれている一部のパフォーマンス機能を破壊する可能性があることです。(「状態サーバーモード」または「SQLサーバーモード」)。oopモードでは、セッションデータをページリクエストの最後にシリアル化し、ページリクエストの最初にデシリアライズする必要があるため、コストがかかる可能性があります。パフォーマンスを向上させるために、SessionStateは、最初にアクセスされたときに変数だけをデシリアライズすることで必要なものだけをデシリアライズしようとし、変更された変数のみを再シリアライズして置き換えます。多くのセッション変数があり、それらをすべて1つのクラスに移動する場合、基本的に、セッションを使用するすべてのページリクエストでセッション内のすべてがデシリアライズされ、クラスが変更されたために1つのプロパティのみが変更された場合でも、すべてを再度シリアル化する必要があります。たくさんのセッションとoopモードを使用している場合に考慮すべきことです。


4
これを上げるための+1。セッションにInProcを使用していない場合、Ernieは100%正しいです。とにかく、InProcは非常に制限されています。これは、Webファームをサポートしておらず、アプリケーションを再起動すると失われるためです。パフォーマンスコストでは、State Serverモードを使用することで20%のプレミアムが見られ、それに加えてシリアル化コストが追加されることに注意してください。ご想像のとおり、これは高くつく可能性があります。プリミティブ型(int、string、char、byteなど)を使用することにより、シリアル化のオーバーヘッドの一部を回避できます。カスタムオブジェクトはシリアル化に直面します。ユーザーは注意してください。
Zack Jannsen、2012

+1良い点。2つの概念を組み合わせる変更は、このカスタム「セッション」クラスの各プロパティが、セッション内の1つの大きなオブジェクトではなく、asp.netセッション自体を呼び出すようにすることです。@ M4Nのアプローチが回避する型キャストを実行する必要がありますが、毎回一部のセッションのみを読み取る場合は、その価値があるかもしれません。
eol

12

私の前に提示された答えは問題に対する適切な解決策を提供しますが、このエラーが発生する理由を理解することが重要であると私は感じています:

Sessionプロパティは、その特定のリクエストに関連するPageタイプのインスタンスを返しますHttpSessionStatePage.Session実際にはを呼び出すことと同じPage.Context.Sessionです。

MSDNはこれがどのように可能であるかを説明しています:

ASP.NETページにはSystem.Web名前空間(HttpContextクラスを含む)へのデフォルトの参照が含まれているためHttpContext、への完全修飾クラス参照なしで.aspxページののメンバーを参照できますHttpContext

ただし、App_Codeのクラス内でこのプロパティにアクセスしようとすると、クラスがページクラスから派生していない限り、プロパティを使用できません。

このよく遭遇するシナリオに対する私の解決策は、ページオブジェクトをクラスに渡さないことです。必要に応じて、Sessionページから必要なオブジェクトを抽出し、名前と値のコレクション/配列/リストの形式でクラスに渡します。


それは素晴らしい説明です、それは私がそれのために+1するのを助けました:)
Owais Qureshi

1

カスタムセッションクラス内のセッション変数を操作しようとしたため、同じエラーが発生しました。

現在のコンテキスト(system.web.httpcontext.current)をクラスに渡す必要があり、その後すべてがうまくいきました。

MA


1

asp.netコアでは、これは動作が異なります。

public class SomeOtherClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    private ISession _session => _httpContextAccessor.HttpContext.Session;

    public SomeOtherClass(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void TestSet()
    {
        _session.SetString("Test", "Ben Rules!");
    }

    public void TestGet()
    {
        var message = _session.GetString("Test");
    }
}

ソース:https : //benjii.me/2016/07/using-sessions-and-httpcontext-in-aspnetcore-and-mvc-core/


0

これは、アプリケーションと開発者の両方にとってより効率的であるはずです。

次のクラスをWebプロジェクトに追加します。

/// <summary>
/// This holds all of the session variables for the site.
/// </summary>
public class SessionCentralized
{
protected internal static void Save<T>(string sessionName, T value)
{
    HttpContext.Current.Session[sessionName] = value;
}

protected internal static T Get<T>(string sessionName)
{
    return (T)HttpContext.Current.Session[sessionName];
}

public static int? WhatEverSessionVariableYouWantToHold
{
    get
    {
        return Get<int?>(nameof(WhatEverSessionVariableYouWantToHold));
    }
    set
    {
        Save(nameof(WhatEverSessionVariableYouWantToHold), value);
    }
}

}

ここに実装があります:

SessionCentralized.WhatEverSessionVariableYouWantToHold = id;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.