ASP.NET 5 MVC 6(コア)アプリケーションを書いています。これで、オブジェクトをセッションキャッシュ(ISession
)に格納(設定および取得)する必要がでてきました。
ご存知かもしれませんが、Set
のISession
メソッドはbyte-array
およびGet
- methodは1を返します。
非コアアプリケーションでは、BinaryFormatter
を使用してオブジェクトを変換します。しかし、コアアプリケーションでどうすればよいですか?
オブジェクトをJSONにシリアル化し、ISession
の拡張メソッドを使用してstring
として保存します。
_// Save
var key = "my-key";
var str = JsonConvert.SerializeObject(obj);
context.Session.SetString(key, str);
// Retrieve
var str = context.Session.GetString(key);
var obj = JsonConvert.DeserializeObject<MyType>(str);
_
ISession
の拡張メソッドは、Microsoft.AspNet(Core).Http
名前空間で定義されます。
これは常緑樹の投稿であり、問題はまだ新鮮であり、Microsoftがオブジェクトをセッションに保存するためのシリアル化を推奨していますが、オブジェクトが読み取り専用でない限り、これは正しい解決策ではありません。すべてのシナリオを説明するブログがあります こちら そして、私はAsp.Net CoreのGitHubの問題を指摘ID 18159 でも指摘しました
問題の概要は次のとおりです:
A.シリアル化はオブジェクトと同じではありません。分散サーバーのシナリオで役立ちますが、Microsoftが強調表示できなかった警告が付いています-そのオブジェクトが読み取られ、書き戻されない場合にのみ、予期しないエラーが発生することなく機能します。
B.セッションで読み書き可能なオブジェクトを探していた場合、逆シリアル化後にセッションから読み取ったオブジェクトを変更するたびに、シリアル化を呼び出してセッションに再度書き込む必要があります。これだけでも、変更を追跡する必要があるか、プロパティが変更されるたびにセッションに書き戻す必要があるため、複数の複雑さ。サーバーへの1つの要求では、応答が返されるまでオブジェクトが複数回書き戻されるシナリオがあります。
C.セッション内の読み取り/書き込みオブジェクトの場合、ユーザーのアクションによってサーバーへの複数の迅速な要求がトリガーされ、システムがオブジェクトを見つける状況が頻繁に発生するため、単一のサーバーでも失敗します。あるスレッドによってシリアル化または非シリアル化され、編集されてから別のスレッドによって書き戻されると、結果として、スレッドによってオブジェクトの状態が上書きされてしまいます。オブジェクトは実際のオブジェクトではないので、ロックをしてもあまり役に立ちませんしかし、逆シリアル化によって作成された一時オブジェクト。
D.複雑なオブジェクトのシリアル化には問題があります。これは単なるパフォーマンスヒットではなく、特定のシナリオで失敗する可能性もあります。特に、それ自体を参照する深くネストされたオブジェクトがある場合はなおさらです。
ソリューションの概要はこちらです、コードとともに完全な実装はブログにあります link :
まず、これをCacheオブジェクトとして実装し、一意のセッションごとにIMemoryCacheに1つのアイテムを作成します。
キャッシュをスライディング有効期限モードに維持して、読み込まれるたびに有効期限を復活させる-それにより、セッションがアクティブである限り、オブジェクトをキャッシュに保持します。
2番目の点だけでは十分ではありません。ハートビートテクニックを実装する必要があります-JavaScriptからTマイナス1分ごとにセッションへの呼び出しをトリガーします。 (これは、ユーザーがブラウザで作業するまでセッションを存続させるためにも使用されていたので、違いはありません。
その他の推奨事項
A. SessionManagerというオブジェクトを作成します。これにより、セッションの読み取り/書き込みに関連するすべてのコードが1か所に配置されます。
B.セッションタイムアウトの値をあまり高くしないでください-ハートビートテクニックを実装している場合は、セッションタイムアウトは3分でも十分です。