ASP 。
- ASP.NETプロセス内のサーバーメモリにセッション情報を保存する
- 状態サーバーにセッション情報を保存する
- 事前定義されたスキーマでSQL Serverデータベースにセッション情報を保存する
しかし、すぐに使えるオプションがいくつあっても、開発者が直面するタスクに完全に答えることはできません。 この記事では、
ASP.NET (MVC)用の独自のセッション状態プロバイダーを実装する方法について説明し
ます 。
セッションストレージは
SQL Serverになり
ます 。
EntityFrameworkを介してデータベースを
操作します。
目次
- なぜこの記事を書いているのですか?
- 独自のプロバイダーを実装する理由
- ASP.NETでセッションを管理する人と方法
- セッションプロバイダーの実装
- テストプロバイダー
- おわりに
なぜこの記事を書いているのですか?
長い間、私は
phpでサイトを開発していました。 ある時点で、私は何か新しいことを学ぶことにし、そのためにASP.NETを選択しました。 phpセッションのプリズムを通して、ASP.NETの承認、メンバーシップ、および役割は、それがどのように機能するかを理解していないことから多くの質問と不満を引き起こしました。
数年後、その仕組みを説明するだけでなく、ASP.NETには独自の方法で変更および実行できないものがないことを示すために、一連の記事を作成することにしました。
独自のプロバイダーを実装する理由
サポートされていないストレージを使用する
マイクロソフト製品は非常に高価であり、事実であり、無料版には多くの制限があります。 したがって、
MySQLや
PostgreSQLなどの別のデータベースを無料版で使用することをお勧めし
ます 。
一方、
Key-Valueストレージを使用して、分散アプリケーションのパフォーマンスを向上させることができます。 または、購入した他社の製品のライセンスを持っているだけかもしれません。
カスタムデータベーステーブルスキーマ
この理由は最も一般的です。
標準機能は優れていますが、アプリケーションが複雑になるほど、その作業に必要な非標準ソリューションが増えます。
例:サイトには、特定のユーザーのセッションを閉じる(強制ログアウトする)機能が必要です。 セッションにはユーザーメンバーシップ情報が保存されないため、SQL Serverの標準データベーススキーマはこの機能をサポートしません。
ASP.NETでセッションを管理する人と方法
SessionStateModuleは状態(セッション)の処理を担当し、デフォルトのハンドラーです。 必要に応じて、セッションの処理を担当する独自の
http-moduleを実装できます。
SessionStateModuleオブジェクトは、操作中に特定のプロバイダーメソッドを呼び出すことにより、セッションプロバイダーと対話します。 モジュールを使用するセッションプロバイダーは、Webアプリケーションの構成に基づいて決定します。 すべてのセッションプロバイダーは、
SessionStateStoreProviderBaseクラスから継承する必要があります。このクラスは、
SessionStateModuleに必要なメソッドを定義します。
セッションスキーム
以下は、ASP.NETでセッションがどのように機能するかをよりよく理解するための、プロバイダーメソッドの呼び出しの概要です(クリック可能)。
図 セッションを操作するためのメソッド呼び出しのシーケンスまず、
SessionStateModuleは、このページ(ASP.NET WebForms)またはコントローラー(ASP.NET MVC)のセッションモードを決定します。
ページに属性が設定されている場合:
<%@ Page EnableSessionState = "true | false | ReadOnly"%>
(またはASP.NET MVCの
SessionState属性)
セッションでのその動作は、
読み取り専用モード(読み取り専用)で発生し、全体的なパフォーマンスがわずかに向上します。 それ以外の場合、
SessionStateModuleモジュールは排他的アクセスを要求し、セッションのコンテンツをブロックします。 ロックは、クエリの最終段階でのみ解放されます。
セッションロックが必要なのはなぜですか?
ASP.NETアプリケーションはマルチスレッドアプリケーションであり、
Ajaxテクノロジーは非常に人気があります。 競合を避けたり、保存されている値を上書きしたり、古い値を取得したりするために、複数のスレッドが同時に同じユーザーのセッションを使用するという状況が発生する場合があります。
ロックは、複数のスレッドから同じユーザーのセッションにアクセスする場合にのみ発生します。
セッションリソースにアクセスしたスレッドは、要求の期間中に最初に排他的アクセスを取得します。 残りのスレッドは、リソースが解放されるか、短いタイムアウトが発生するまで待機します。
スレッド間に競合がない、または重大な結果をもたらさないと信じる理由がある場合、サポートをブロックせずにプロバイダーを実装できます。
セッションプロバイダーの実装
セッションデータを保存するテーブルの作成
次のテーブル構造を使用して、セッション状態データを保存します。
ブロックをサポートします。 また、必要に応じて、セッションを所有するユーザーに関する情報を保存するために
UserIdフィールドを追加しました(たとえば、ユーザーに管理パネルから強制的にログアウトさせるため)。
セッション | 独自の文字列ラベル。当社が生成したものではありません。 ラテンアルファベットの文字と数字で構成される文字列にエンコードされたこの乱数は、 最大 24文字の長さに達します。 |
作成しました | セッション作成時間。 |
期限切れ | セッションが期限切れになる時間。 |
ルックデート | セッションがブロックされた瞬間。 |
Lookid | セッションロック番号。 |
見た | 現時点でロックはありますか? |
アイテムの内容 | 直列化された形式のセッションコンテンツ。 |
ユーザーID | セッションが属するユーザーのID(ゲストのIDは1です) |
上記のテーブルを作成するSQLクエリ(SQL Server):
CREATE TABLE [dbo].[Sessions] ( [SessionId] varchar(24) COLLATE Cyrillic_General_CI_AS NOT NULL, [Created] smalldatetime NOT NULL, [Expires] smalldatetime NOT NULL, [LockDate] smalldatetime NOT NULL, [LockId] int NOT NULL, [Locked] bit CONSTRAINT [DF_Sessions_Locked] DEFAULT 0 NOT NULL, [ItemContent] varbinary(max) NULL, [UserId] int NOT NULL, CONSTRAINT [PK_Sessions] PRIMARY KEY CLUSTERED ([SessionId]) ) ON [PRIMARY] GO
EntityFrameworkデータモデルの作成
SQLクエリを手動で記述しないようにして時間を節約したいので、ADO.NET
EntityFrameworkを使用します。 ただし、SQLクエリを手動で作成する場合と比較して、コードのパフォーマンスが少し低下します。
これを行うには、
ADO.NET Entity Data Modelウィザードを使用して、必要なモデルを作成します。
図 データモデルを作成するためのADO.NETエンティティデータモデルウィザードの選択作成したエンティティに
DbSessionという名前を付けました。 その後、データベースとやり取りするために必要なクラスとコンテキストを作成するために、コード生成テンプレートを使用します。 コンテキストは、データベースから
のエンティティの
コレクションを管理します。
図 コード生成パターンを適用するためのメニュー選択私が選択する
EntityFrameworkの4.1バージョンから利用できる
DbContext APIが好きです。
図 コード生成テンプレートとしてDbContextを選択するこれで、
CommonEntitiesと呼ばれるコンテキストと
DbSessionクラスができました。 プロバイダーの実装を開始できます。
プロバイダーの実装
最初に、基本クラス
SessionStateStoreProviderBaseから継承する
クラスを作成する必要があります。
using QueryHunter.WebDomain.Layouts.Session; public class SessionStateProvider : SessionStateStoreProviderBase {
次に、いくつかのメソッドを実装する必要があります。これらのメソッドについては、
ドキュメントまたはコメント付きの以下のコードで詳しく説明します。
構成設定
プロバイダーを実装したら、構成に登録する必要があります。 これを行うには、次のコードを
<system.web>セクションに追加します。
同時に、
CustomSessionStateProvider.Infrastructure.SessionProvider.SessionStateProviderは、名前空間を含むプロバイダーの完全なクラス名です。 あなたはおそらくそれを持っているでしょう。
テストプロバイダー
セッションの動作を実証するために、空の
ASP.NET MVC 3アプリケーションを作成し、
HomeControllerを作成し、
リストやユーザークラスオブジェクトを含むさまざまな要素を表示してセッションに書き込む一連のアクションを定義しました。
namespace CustomSessionStateProvider.Controllers { public class HomeController : Controller {
ビューの内容は説明しませんが、記事の最後にソースコードへのリンクがあります。 代わりに、ブラウザで取得した結果を表示し、コントローラーアクションを順番に呼び出します。
おわりに
結論として、標準から逸脱することを恐れる必要はないことを付け加えます。多くの場合、独自のソリューションにより、より生産的で柔軟なアプリケーションを作成できます。
次の記事では、独自のASP.NETメンバーシップメカニズムを作成する方法について説明します。
見てくれてありがとう、良い週末を!
PSソースコードは、
CustomSessionStateStoreProvider.zipで入手できます。
便利なリンク
Kiris Muzykovによる
Redisを使用したセッションストアプロバイダーASP.NETの記述(
kmuzykov )
セッションステートストアプロバイダー (msdn)の実装
セッションステートストレージプロバイダー (msdn)の例
ハリー・キンペルによる
MySQLプロバイダー