ASP.NET MVC 4アプリケーションでセッションを使用する方法


113

ASP.NET MVCは初めてです。以前にPHPを使用したことがあり、セッションを作成し、現在のセッション変数に基づいてユーザーレコードを選択するのは簡単でした。

C#ASP.NET MVC 4アプリケーションでセッションを作成して使用する方法を示す簡単なステップバイステップチュートリアルをインターネットの至る所で探しました。コントローラーの任意の場所からアクセスできるユーザー変数を使用してセッションを作成し、LINQクエリで変数を使用できるようにしたいと考えています。



2
この記事は興味深いかもしれません:brockallen.com/2012/04/07/think-twice-about-using-session-state
Daniel Hollinrake

回答:


160

試す

//adding data to session
//assuming the method below will return list of Products

var products=Db.GetProducts();

//Store the products to a session

Session["products"]=products;

//To get what you have stored to a session

var products=Session["products"] as List<Product>;

//to clear the session value

Session["products"]=null;

3
ジョベール、ありがとう!あなたは私にアイデアを与えました!ただ不思議に思っています..、ログイン中にユーザー変数をセッションに追加することは可能ですか?また、アプリケーションのさまざまなコントローラー間でセッション変数(1回だけ作成)にアクセスできますか?
Thuto Paul Gaotingwe 2013年

31
セッションには、あらゆるタイプのあらゆるデータを保存できます。一度作成すると、すべてのビューとコントローラー全体でそれに保存されている値にアクセスできます。作成されたセッションには、ユーザーおよびブラウザごとにのみアクセスできることにも注意してください。Firefoxを使用してUser1によって作成されたセッションに、IEを使用して同じユーザーがアクセスできないことを意味します。セッションなどでやってはいけないこともあります。大きなデータを保存しないでください。これにより、サーバーのパフォーマンスが低下する場合があります。最後に、機密データをパスワードやクレジットカード番号などのセッションに保存しないでください
Jobert Enamno 2013年

2
もう一度ありがとう!異なるコントローラー間でアクセスできるようにするには、どこに作成しますか?
Thuto Paul Gaotingwe 2013年

2
@JobertEnamnoはWebSecurity.CurrentUserId、データベースから何度もプルしないように、取得した値を保存しても安全ですか(非常にコストがかかることがわかりました)?
AndriusNaruševičius14年

2
クロスコントローラーセッションはないため、別のコントローラーを要求すると(たとえば、Account/LogOnからHome/IndexSession["FirstName"]はになりnullます。開発者は、親コントローラー(BaseController)を作成し、internal protected HttpSessionStateBase SharedSessionすべてのサブコントローラーで共有セッション変数を公開する保護フィールド()を定義する必要があります(これは、すべてのアプリコントローラーがから継承することを前提としていますBaseController
Bellash

63

Webのステートレスな性質により、セッションは、オブジェクトをシリアル化してセッションに保存することにより、リクエスト全体でオブジェクトを永続化する非常に便利な方法でもあります。

これは、アプリケーション全体で定期的な情報にアクセスする必要があり、リクエストごとに追加のデータベース呼び出しを保存する必要がある場合に、このデータをオブジェクトに保存して、リクエストごとにシリアル化解除することができます。

再利用可能でシリアライズ可能なオブジェクト:

[Serializable]
public class UserProfileSessionData
{
    public int UserId { get; set; }

    public string EmailAddress { get; set; }

    public string FullName { get; set; }
}

使用事例:

public class LoginController : Controller {

    [HttpPost]
    public ActionResult Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            var profileData = new UserProfileSessionData {
                UserId = model.UserId,
                EmailAddress = model.EmailAddress,
                FullName = model.FullName
            }

            this.Session["UserProfile"] = profileData;
        }
    }

    public ActionResult LoggedInStatusMessage()
    {
        var profileData = this.Session["UserProfile"] as UserProfileSessionData;

        /* From here you could output profileData.FullName to a view and
        save yourself unnecessary database calls */
    }

}

このオブジェクトがシリアル化されると、それを作成したり、データベース内に含まれるデータを再度データベースに照会したりする必要なく、すべてのコントローラーで使用できます。

依存性注入を使用してセッションオブジェクトを注入する

理想的な世界では、「実装ではなくインターフェイスにプログラミングし、選択したInversion of Controlコンテナーを使用して、シリアル化可能なセッションオブジェクトをコントローラーに挿入します(この例では、StructureMapを使用しています。 )。

public class WebsiteRegistry : Registry
{
    public WebsiteRegistry()
    {
        this.For<IUserProfileSessionData>().HybridHttpOrThreadLocalScoped().Use(() => GetUserProfileFromSession());   
    }

    public static IUserProfileSessionData GetUserProfileFromSession()
    {
        var session = HttpContext.Current.Session;
        if (session["UserProfile"] != null)
        {
            return session["UserProfile"] as IUserProfileSessionData;
        }

        /* Create new empty session object */
        session["UserProfile"] = new UserProfileSessionData();

        return session["UserProfile"] as IUserProfileSessionData;
    }
}

次に、これをGlobal.asax.csファイルに登録します。

セッションオブジェクトの挿入に慣れていない方のために、この件に関するより詳細なブログ投稿をここで見つけることができます。

警告の言葉:

セッションは最小限に抑える必要があることに注意してください。大きなセッションはパフォーマンスの問題を引き起こし始める可能性があります。

機密データ(パスワードなど)を保存しないこともお勧めします。


ただし、クラス定義はどこに配置しますか?私はまだすべてにかなり新しいですが、他のコントローラーがクラスをどのように見て、それが何であるかを知りたいと思っています。コントローラーの上部に追加するだけですか?global.asaxのSessionStartで初期化することを考えていましたが、それが最善の方法ではないかもしれません。
Shaun314 2014

@ Shaun314理想的には、IoCコンテナーを使用して、依存関係の注入を介してオブジェクトをコントローラーに注入します(編集を参照)。
ジョセフウッドワード

1
Identity 2を使用してユーザーにログインした後、いくつかのセッション情報を保存しています。ユーザーをリダイレクトする最初のアクション以外の他のアクションおよびコントローラーでこれらの情報を取得できません。何か案が?
Akbari 2015

17

これは、ASP.NETおよびASP.NET MVCでセッション状態がどのように機能するかです。

ASP.NETセッション状態の概要

基本的に、これを実行して、Sessionオブジェクトに値を格納します。

Session["FirstName"] = FirstNameTextBox.Text;

値を取得するには:

var firstName = Session["FirstName"];

10
クロスコントローラーセッションはないため、たとえばfromからAccountに別のコントローラーを要求するとHome、Session ["FirstName"]はnullになります。開発者は、すべてのサブコントローラーで共有変数を公開BaseControllerする保護フィールド(internal protected HttpSessionStateBase SharedSession)を作成して定義する必要がありますSession(これは、すべてのアプリコントローラーがから継承することを前提としていますBaseController
Bellash

4
ええと、確かにありますか?コントローラー(MVCによって提供される基本コントローラー)にセッション変数があります。
aeliusd

7
@ベラッシュこれは完全に間違っています。セッションは、コントローラー全体で使用できます。HomeControllerでSession ["test"]を設定し、それをAccountControllerで読み取ります。
niico

0

以下を使用して、セッションにあらゆる種類のデータを保存できます。

Session["VariableName"]=value;

この変数は20分ほど続きます。


-8

Uは、Session ["FirstName"] = FirstNameTextBox.Text;のようなセッションに任意の値を格納できます。しかし、モデルの静的フィールドとして値を割り当てることをuに推奨します。uは、アプリケーションの任意の場所でそのフィールド値にアクセスできます。セッションは必要ありません。セッションは避けてください。

public class Employee
{
   public int UserId { get; set; }
   public string EmailAddress { get; set; }
   public static string FullName { get; set; }
}

コントローラ上-Employee.FullName = "ABC"; これで、アプリケーションのどこからでもこのフルネームにアクセスできます。


10
静的フィールド、特に従業員名などのユーザーデータにデータを保存すると、マルチユーザー環境で深刻な問題が発生します。2人の異なるユーザーがシステムにログインすると、Employeeの静的フィールドが各インスタンスで同じであるため、同じEmployee.EmailAddressが表示されます。
GökçerGökdal
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.