基本的に物理検査プロセスのデータ入力画面であるASP.netアプリケーションがあります。ユーザーは、複数のブラウザウィンドウを開いて、複数の検査からのデータを同時に入力できるようにしたいと考えています。最初はCookieベースのセッションを使用していましたが、明らかにこれは爆発しました。
私はCookieを使用しないセッションを使用するように切り替えました。セッションはURLに保存され、テストでは問題が解決したようです。各ブラウザウィンドウ/タブには異なるセッションIDがあり、一方に入力されたデータは、もう一方に入力されたデータを上書きしませんでした。
しかし、私のユーザーは思ったよりも効率よく物事を壊し、ブラウザー間で同じセッションを取得できるようにしているようです。アプリケーションを開くために、あるタブから別のタブにアドレスをコピーして貼り付けていると思いますが、まだ確認できていません(別の場所にあるため、簡単に尋ねることはできません) )。
コピーして貼り付けない、または一度に1つだけ入力するように説得する以外に、この状況が発生しないようにするにはどうすればよいですか?
ViewStateは状態情報をクライアント(HTMLページ)にレンダリングするため、Sessionの代わりにViewStateを使用することを検討してください。ブラウザのセッション動作を詳細に制御できるかどうかはわかりません。セッションIDは、メーカーが行った方法でブラウザによって維持されるためです。したがって、ViewStateは、将来のブラウザバージョンだけでなく、より予測可能です。
セッションを1つの検査プロセスのみを処理するように制限し、ユーザーが複数の検査で同時に作業できるように、複数のセッションを強制する理由がわかりません。それはかなり厄介な孤立のスタイルのように感じます。
Webアプリケーション(およびページ)は、単一のユーザーセッション内で複数の検査プロセスを処理できる必要があります。
セッション変数に保持されているデータはすべて、単一の処理のために明確に公開されるべきではありません。それらは、どのデータセットがどの検査プロセスに属しているかを容易に識別するコレクションに格納する必要があります。 Every Webサーバーへのページ送信では、適切なセッションセットを照合してプルして使用できるように、関連する検査プロセスの識別子を保持する必要があります。
擬似コードの概念
var inspectionID = this.inspectionLabel.Text;
var inspectionSets = (Hashtable)Session["inspections"];
var inspection = (Inspection)inspectionSets[inspectionID];
これは非常に良い質問です。
メインのWebページをiframeに保存します。 JavaScriptを使用して、Webページがまだ親iframeにあるかどうかを確認してください。そうでない場合は、複数のブラウザウィンドウを開いています。
アプリ全体がiframe対応であることを確認する必要があります。
さまざまな物理的検査にアクセスするには、ユーザーはさまざまなアカウントでログインする必要がありますか? PhysicalInspectionID
がURLの一部である限り、複数の物理検査を同時に編集しても問題はないようです。
例えば。、
http://inspections.mydomain.com/edit/2
もちろん、URLをコピーすると、他のウィンドウの複製が取得されますが、これにより、コピーしないように指示されます。代わりに、別のウィンドウを開き、UIを介して適切な検査を参照(または新しい検査を追加)します。
これは、認証されたユーザーが複数のタブを開くことを禁止するためにASP.NET MVCで使用するものです。
<script language="javascript" type="text/javascript">
@if(Request.IsAuthenticated)
{
<text>
if (window.name != 'singleWindow') {
window.location.href = "Content/ErrorPages/SingleTab.htm";
}
</text>
}
else
{
<text>
window.name = "singleWindow";
</text>
}
</script>
基本的に、これはユーザーがログインページに初めてアクセスしたときにウィンドウ名を設定します。ログイン後、後続の各ページ読み込みでウィンドウ名がテストされます。
2つの問題:
この問題の解決策は、次の方法で実装できます。
public static class CommonHelper
{
public static bool SiteGuard
{
get
{
if(HttpContext.Current.Session["SiteGuard"] == null)
return true;
return (bool)HttpContext.Current.Session["SiteGuard"];
}
set
{
HttpContext.Current.Session["SiteGuard"] = value;
}
}
}
public partial class TestPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
bool go = false;
for(int i = 0; i < 50; i++) // wait for the service to work (5 secs max)
{
if(CommonHelper.SiteGuard)
{
go = true;
break;
}
Thread.Sleep(100);
}
if(!go)
Response.Redirect("Login.aspx");
SiteGuard = false; // from now on, nobody can visit your site
}
// Now as long as Page.IsPostBack is true you are in a good shape
}
}
Asmx Webサービス(または適切と思われる他のタイプのサービス)をルートプロジェクトに追加し、次のメソッドを追加します。
[WebMethod(EnableSession = true)]
public void FreeSiteGuard()
{
HttpContext.Current.Session["SiteGuard"] = null;
}
マスターページまたはすべてのページで、次のJavaScriptを追加します。
<script type="text/javascript">
window.onbeforeunload = function (e) {
e = e || window.event;
if (e) {
// Invoke web service
YourProject.YourWebServiceName.FreeSiteGuard();
}
};
</script>
サイトの応答時間は、Webサービスの速度に影響されることに注意してください。
リクエストにリファラーがない場合は、新しいsessionIdを作成します。これで、URLのコピーと貼り付けの問題が解決します。以前と同じように、sessionIdをURLに保存します。