miso_soup3 Blog

主に ASP.NET 関連について書いています。

ASP.NET MVC セッション状態の値を操作してみる

by 深夜連絡 ASP.NET MVC な Web アプリ Advent Calendar 2013 6 日目

今回は、ASP.NET の機能「セッション状態」(セッション情報、Session とも呼ばれる)、値の取得・設定の操作を行ってみます。
ここでは、チュートリアルを通して以下のことを確認します。

  • セッション状態とは
  • 準備
  • 値を取得・設定・削除を試してみる
  • Session.RemoveAll() と Session.Abandon() のちがい
  • セッションはどうやって判別しているか

「セッション状態」は ASP.NET Web Fomrs でも使用できる ASP.NET のコア機能ですが、ここでは ASP.NET MVC での操作を例としています。

セッション状態とは

「セッション状態」とは、ページ間で値を共有するための仕組みの1つです。
(他の仕組みは、クッキーやキャッシュ等があります。)

クライアント側で値を保存するクッキーとは違い、「セッション状態」では値をサーバー側で保存します。

概要を知るには、下のサイトをご参考下さい。

準備

「セッション状態」の値の操作を試すため、ASP.NET MVC で簡単なページを用意します。

このようなページ↓を用意し、各ページにアクセスすることで、「セッション状態」の値を操作し、結果を確認します。

f:id:miso_soup3:20131209064259p:plain

ASP.NET MVC のプロジェクトを用意し、HomeController クラス と、View/Home/ViewSession.cshtml を用意します。

HomeController クラスのコードは下のようになります。

using System.Web.Mvc;

namespace MySessionProject.Controllers
{
	public class HomeController : Controller
	{
		//1.セッション状態の値を表示
		[HttpGet]
		public ActionResult ViewSession()
		{
			GetSessionValue();
			return View();
		}

		//2.セッション状態の値を設定
		[HttpGet]
		public ActionResult InputSession()
		{
			//セッション状態に値を設定します。
			Session["Drink"] = "Coffe";
			
			GetSessionValue();
			return View("ViewSession");
		}

		//3.Session.RemoveAll() を実行
		[HttpGet]
		public ActionResult RemoveAll()
		{
			//セッション状態の値を削除
			Session.RemoveAll();
			
			GetSessionValue();
			return View("ViewSession");
		}

		//4.Session.Abandon() を実行
		[HttpGet]
		public ActionResult Abandon()
		{
			//セッションを終了する
			Session.Abandon();
			
			GetSessionValue();
			return View("ViewSession");
		}

		private void GetSessionValue()
		{
			//セッション状態の値を取得します。
			object drink = Session["Drink"];
			ViewBag.Drink = drink;
		}

	}
}

すべてのアクションにて、GetSessionValue() メソッドを通して、セッション状態の値 キー「Drink」を取得してページに表示させています。(値は ViewBag.Drink に格納しビューに渡しています。)
また、すべてのアクションは、return View("ViewSession"); で、ViewSession.cshtml を表示しています。つまり、すべて GET でページを表示させています。(リダイレクトは行っていません。)

セッション状態の値を設定するには

Session["キー"] = 値;

セッション状態の値を取得するには

Session["キー"]

で取得できます。

ViewSession.cshtml は下のようになります。(View フォルダの Home フォルダ内に配置します。)

@{ ViewBag.Title = "Session"; }

<h2>現在のアクション:@ViewContext.RouteData.Values["action"]</h2>

セッション状態 キー「Drink」の値:@ViewBag.Drink

<ul>
	<li>@Html.ActionLink("1.ViewSession - セッション状態の値を表示", "ViewSession")</li>
	<li>@Html.ActionLink("2.InputSession - セッション状態の値を設定", "InputSession")</li>
	<li>@Html.ActionLink("3.RemoveAll - Session.RemoveAll() を実行", "RemoveAll")</li>
	<li>@Html.ActionLink("4.Abandon - Session.Abandon() を実行", "Abandon")</li>
</ul>

今どのアクションによってページを表示させているかわかるように、アクション名を表示しています。
また、セッション状態の値 キー「Drink」を表示しています。

以上で準備はおわりです。F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスするとこから始めます。

値を取得・設定・削除を試してみる

最初は何も表示されない
  • F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスします。

値を設定していないので、キー「Drink」の値は何も表示されません。

値を設定して表示する
  • F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスします。
  • 「2.InputSession - セッション状態の値を設定」をクリックします。
  • 「1.ViewSession - セッション状態の値を表示」をクリックします。

値を保存した後なので、「Coffe」が表示されます。ブラウザを閉じずに、例えば Google のページにアクセスした後でも、「~/Home/ViewSession」にアクセスすると表示されています。

値を削除してみる
  • F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスします。
  • 「2.InputSession - セッション状態の値を設定」をクリックします。
  • 「3.RemoveAll - Session.RemoveAll() を実行」をクリックします。

値が削除されたので、キー「Drink」の値は何も表示されません。
Session.RemoveAll() メソッドは、セッション状態の値を全て削除します。

Session.RemoveAll() と Session.Abandon() のちがい

値を削除してみる2
  • F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスします。
  • 「2.InputSession - セッション状態の値を設定」をクリックします。
  • 「4.Abandon - Session.Abandon() を実行」をクリックします。

「Coffe」が表示されます。が、この後に

  • 「1.ViewSession - セッション状態の値を表示」をクリック

すると、キー「Drink」の値は何も表示されません。

Session.RemoveAll() メソッドは、すぐにセッション状態の値を削除する一方、
Session.Abandon() メソッドは、ページの処理が終わった後に、セッション状態の値を削除しています。
なので、次のリクエストから値が表示されなくなります。

Session.Abandon() については、ASP.NET でセッション ID が再利用されるしくみと理由について
に詳細があります。

セッションはどうやって判別しているか

なぜ、複数のリクエスト間(ページ間)で、値を共有できるのでしょうか?
答えは、クッキーに「セッション ID」を仕込んでいるからです。クッキーはブラウザから送信されます。このクッキーにあるセッション ID によって、複数のリクエストを”同じユーザーが操作してる”と判別しています。

セッション ID を確認してみる
  • F5 でデバッグ実行し、「~/Home/ViewSession」にアクセスします。
  • 「2.InputSession - セッション状態の値を設定」をクリックします。

この時のレスポンスのヘッダーを確認します。

Set-Cookie: ASP.NET_SessionId=(文字列); path=/; HttpOnly

とあるはずです。この(文字列)がセッション ID です。

  • 「1.ViewSession - セッション状態の値を表示」をクリックします。

この時、リクエストのヘッダーにてクッキーが送信されます。

Cookie: ASP.NET_SessionId=(文字列)

デフォルトでは、このクッキーはブラウザを閉じると破棄されるので、セッション状態の値はブラウザを閉じると取得できません。なお、Session.Abandon() や Session.RemoveAll() を実行した後でもこのセッション ID はクッキーで送信されます。

・・・その他セッションの有効時間などなど、セッション状態の機能にはいろいろな作用や設定できる箇所があります。
量が多すぎて、ここでは書ききれない&把握しきれてない・・・・。
「ASP.NET セッション」でぐぐると大量の情報を取得できます。