この 3 日間、私は簡単なことだと思っていたことを達成する方法を見つけるのに苦労しました。自分でこれを行ったり、Web で解決策を探したりしても、役に立ちませんでした。研究をするとき、何を探すべきかさえわからないからかもしれません。ここでできる限り説明しようと思います。誰かが助けてくれるかもしれません。
どのようにやっているのかは言いません。いろいろな方法でやろうとしましたが、どれもさまざまな理由でうまくいかなかったからです。あなたからの新鮮なアドバイスが欲しいです。
Web アプリケーションのほとんどのページには、次のような 2 つのリンクがあります (ただし、さらに多くのリンクがある可能性があります)。
- オプション A
- オプション B
これはコントローラー アクションによって返される部分的なビューです。
ユーザーは値または両方 (すべて) を選択できますが、いずれも選択できないわけではありません。つまり、少なくとも 1 つを常に選択する必要があります。
これらのリンクは、ほとんどすべてのページでアクセスできる必要があり、別のページにリダイレクトすることは想定されていませんが、アクションが返されたコンテンツをフィルタリングする必要がある場合に再利用できるように、この情報をどこかに保存するためだけに使用されます: 現在のコントローラーに関して常にアクセス可能な場所アクションまたはユーザー (認証されていないユーザーを含む) (セッション? Cookie?)。この情報は、Web アプリケーション全体で表示されるコンテンツをフィルタリングするために使用されます。
したがって、問題はそのビジネス ログを作成する方法ではなく、この情報を保存する方法 (および場所) です。
- クエリ文字列をいじらずに(つまり、クエリ文字列をできるだけ空/クリーンに保ちます)
- 他のページにリダイレクトせずに (コンテンツが異なるだけで、ユーザーは現在のページを取得する必要があります)
- ユーザーがもう一度クリックしてオプションを変更するまで、この情報がすべてのビュー間で保持されるようにします
私の目的は、すべてのオプションとその選択ステータス (オン/オフ) を含むモデルにこの情報を保存することです。これにより、適切な PartialView がそれらを表示する方法を知ることができます。また、このモデルをオプションの変更を処理する「もの」に送信することもできます。
ありがとう。
アップデート
Paul のアドバイスに従って、私は Session 方式を採用しました。
private List<OptionSelectionModel> _userOptionPreferences;
protected List<OptionSelectionModel> UserOptionPreferences
{
get
{
if (Session["UserOptionPreferences"] == null)
{
_userOptionPreferences= Lib.Options.GetOptionSelectionModelList();
}
else
{
_userOptionPreferences= Session["UserOptionPreferences"].ToString().Deserialize<List<OptionSelectionModel>>();
}
if (_userOptionPreferences.Where(g => g.Selected).Count() == 0)
{
foreach (var userOptionPreferencesin _userOptionPreferences)
{
userOptionPreferences.Selected = true;
}
}
UserOptionPreferences= _userOptionPreferences;
return _userOptionPreferences;
}
private set
{
_userOptionPreferences= value;
Session["UserOptionPreferences"] = _userOptionPreferences.SerializeObject();
}
}
これに続いて、私はオーバーライドしました(「オーバーライドする」の正しい活用はわかりません:) OnActionExecuting():
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
GetOptionSelections();
base.OnActionExecuting(filterContext);
}
GetOptionSelections()...
private void GetOptionSelections()
{
if (String.IsNullOrEmpty(Request["optionCode"])) return;
var newOptionCode = Request["optionCode "];
foreach (var userOptionPreferencesin UserOptionPreferences)
{
if (userOptionPreferences.OptionCode == newOptionCode )
userOptionPreferences.Selected = !userOptionPreferences.Selected;
}
}
このコードはもっと良くなると思いますが、今はそれを機能させたいだけで、機能しません。
他にも問題があるかもしれませんが (実際には確かに)、主な問題は、OnActionExecuting が BaseController から継承するコントローラーの各アクションによって呼び出されるため、userOptionPreferences.Selected のオン/オフを切り替え続けることだと思いますが、私はしません。 GetOptionSelections() を各ビューで 1 回だけ呼び出す方法がわかりません: 古い Page_Load のようなものですが、MVC 用です。
最後の更新 AKA ソリューション わかりました、セッションの方法を使用して、この情報を保存することができました。
他の問題は実際にはこの質問のトピックではありませんでした。オプションの変更を処理する新しいアクションを作成して解決し、呼び出し元の URL にリダイレクトします (通常の returnUrl パラメーターを使用しますが、アクションパラメーターとして)。このように、オプションの変更は呼び出しごとに 1 回だけ行われます。
私が本当に好きではない唯一のことは、セッション値は変更されず、メモリ内の値のみが変更されるため、UserOptionPreferences プロパティを単純に操作できないことです。そのため、新しいオブジェクトのプロパティを設定する必要があります。毎回のステータス:大したことではありませんが、良くもありません。