4

以前にも同様の質問がありましたが、まだ回答がなく、かなりの時間をかけて回答を見つけました。

シナリオはこうです。フォーム認証/LINQ-to-SQL データ モデルを使用する ASP.NET MVC アプリケーションがあります。

各ユーザーは、1 つ以上のアカウントに関連付けることができます。ログイン時に、アプリケーションは関連付けられているアカウントの数を確認します。

0 = エラー ページに移動し、アクセス権がないことを知らせます
1 =そのアカウントを使用するようにユーザー データを設定します
2 以上= 使用したいアカウントを選択できるページに移動します (変更可能訪問中)

この情報をどのように保存しますか?

さらに、このアカウントをコントローラー アクションのベースとして使用したいと考えています。つまり、その後アクセスするページのデータは、選択したアカウントに関連付けられます。

シングルトンが頭に浮かびますが、それを実装する方法がわかりません。

私が現在調査しているアプローチは、すべてのコントローラーが継承するベースコントローラーです。

  1. ユーザーがログインしているかどうかを確認します。
  2. その場合は、アカウントが選択されているかどうかを確認します
    • いいえ - アカウント選択ページにリダイレクトします
    • はい - 元のリクエストを続行します

これを行うための推奨/ベストプラクティスの方法は何ですか?

ありがとうマルコ

4

2 に答える 2

2

ベースコントローラーは使用しないでください。これは、アクションフィルターを使用して実行できます。これにより、ログオンしているかどうか、アカウントが選択されているかどうかを確認し、エラーページまたはアカウント選択ページにリダイレクトするためのインターセプトポイントが提供されます。filterContext.ResultアクションフィルターのOnActionExecutingメソッド中に、リクエストが通過しないように設定するだけです。コントローラの場合と同じように、アクション中にセッション、一時データ、Cookie、およびHttpContext全体に完全にアクセスできます。また、フィルター属性フィルタープロバイダーを使用して依存性をプロパティ注入できるため、必要なデータアクセスが可能になります。

データのモデリングに関しては、Linq to SQLについてはあまり詳しくありませんが、通常の1対多でうまくいくと思います。

User (1) <-------> (0..*) Account

public class User
{
    public virtual ICollection<Account> Accounts { get; protected internal set; }
}

public class Account
{
    public int UserId { get; protected internal set; }
    public virtual User User { get; protected internal set; }
}

更新:申し訳ありませんが、「ストア」の意味を誤解しました。MVCでは、保存できる方法はいくつかあります。セッション、Cookie、キャッシュ(および、短期間のセッションであるTempData)が最も一般的な選択肢です。私の選択は異なります。セッションはおそらく最も簡単ですが、ロードバランサーを備えたサーバーファームにデプロイされている場合は、ユーザーのセッションが物理マシンをジャンプした場合にどうなるかを考える必要があります。セッションはそのまま残りますか?

ジェレミーが言うように、クッキーもあります。ここでは負荷分散の心配はありませんが、セマンティクスはセッションよりも処理が少し難しいです。たとえば、Cookieを読み取る前に、Cookieを書き込むためにリダイレクトを送信する必要があります。また、期限切れのCookieを追加して削除する必要があるという事実が気に入らなかったのです。このデータはセキュリティの一部であるため、Cookieの値を暗号化することもできます。

キャッシュを使用する場合、データはセッションなどのどこかのメモリに存在する可能性があります(SQLセッションプロバイダーを使用している場合を除く)。Azureを使用しており、そのキャッシュは多くの優れたMVC機能をサポートしていないため、キャッシュはおそらく私の最後の選択肢です。ロードバランサーがユーザーをクラスター内の別のマシンに移動する場合にも同じ問題が発生します。この場合、データを再キャッシュする必要があります。

いずれにせよ、基本のControllerクラスではなく、アクションフィルターを使用する必要があります。

于 2012-05-15T07:17:31.200 に答える
0

どのタイプのスケールについて話しているのですか?ユーザー数は 100 万人ですか、それとも数千人ですか。

私の最初の考えは、キーがログインユーザー名(一意であると仮定)であり、値が関連するアカウントの配列(キーまたはすべてのデータ)である辞書を作成することです。次に、辞書をキャッシュに入れます。新しい関連付けが作成されるたびに期限切れになります。

このアプローチにはいくつかの問題があります。まず、新しい関連付けが作成される速度はどのくらいですか? それらが常に作成されている場合、キャッシュは議論の余地があります。あなたはいつもDBに行きます。第 2 に、何百万ものユーザー/関連付けがある場合、それらすべてをキャッシュに入れることは実用的ではない可能性があります。

別の可能性は、セッション状態サーバーです。これは、関係の保存専用です。

さらに別の可能性は、データセットのサイズに応じて、毎回データベースにクエリを実行することです。データ セットのサイズが大きくなり、リアルタイム データを毎回プルすることが現実的でない場合は、ニーズに合ったソリューションを設計できます。

リクエスト間で選択したアカウントを永続化する場合、オプションはCookie、URL、またはデータベースのいずれかです(ユーザーのフィールド、つまりCurrentAccountである可能性があります。このアプローチは少し面倒です)。

MVC を使用しているので、URL を使用します。ルーティングとカスタム ルート制約を使用すると、アカウントを含む URL を作成できます。ユーザーはログインする必要があるため、ユーザー ID は既にわかっています。

例: http://www.acme.com/{account}/edit/

ユーザーがログインしているかどうかの確認は、Global.asax のアクション フィルターまたは Application_AuthenticateRequest で処理できます。認証は、ASP.NET でかなり適切に実装されています。その多くは、web.config の構成値によって駆動されます。

認証が確認された後、同じ方法でアカウントのリダイレクトが行われる可能性があります。または、待機してアクション フィルターをチェックインすることもできます。

于 2012-05-15T15:21:54.173 に答える