今更枯れた技術のASP.NET WebFormですが、企業内ではまだまだ使われていると思います。
そういった中で、セッションタイムアウト処理ではまりましたので忘備録的に置いておきます。
UpdatePanelではResponse.Redirectが使えない
通常はセッションタイムアウトになったときに、「Response.Redirect」をつかってログインページやホームなどにページ転送(リダイレクト処理)をさせると思います。
protected void Page_Load(object sender, EventArgs e)
{
if (Session["ID"] == null)
{
//セッションが取れなければ、ログインページへ
Response.Redirect("login.aspx");
}
}
単純なポストバック処理であれば、ちゃんとログインページへ転送されて何の問題もないのですが、UpdatePanel内のアクションが発生した場合では残念ながらページ転送処理の「Response.Redirect」の部分で例外エラーが発生してしまいます。(ちなみにデバッグでは何事もなかったようにスルーされる)
なぜUpdatePanelではエラーが発生するのかというと、UpdatePanel自体はページではなく、あくまでページの一部分だからです。
なので、UpdatePanelのイベントは「AsyncPostBack」になりますので、「IsInAsyncPostBack」で判断して、その時だけページ転送の処理を行わないようにすればいいのです。
//ScriptManagerのIsInAsyncPostBackプロパティで判断する
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
//AsyncPostbackなら何もしない
return;
}
else
{
//Postbackなら転送
Response.Redirect("login.aspx");
}
ですが、UpdatePanel内ではアクションしても反応なしになってしまいますので、それでもなんとか転送してくれといわれる場合があります。
それでなんとか処理したのがこちらです。
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
{
//AsyncPostback
string script = "window.open('login.aspx','_self');";
ScriptManager.RegisterStartupScript(updatepanel, updatepanel.GetType(), "redirect", True);
}
else
{
//Postback
Response.Redirect("login.aspx");
}
こんな感じで、書けばセッションタイムアウトになった場合でも対象となった「updatepanel」に対して、「RegisterStartupScript」を使ったJavascriptでの転送処理を使うと同じように強制的にログインページに飛ばせます。
複数のUpdatePanelで処理する場合などでは、こんな関数でコントロールを取得すれば個別に対応できます。
//AsyncPostBackのControlを取得する
private Control GetAsyncPostBackControl(Page page)
{
Control ctrl = null;
//"__EVENTTARGET"からControl名を取得
string ctrlName = Page.Request.Params.Get("__EVENTTARGET");
if (!String.IsNullOrEmpty(ctrlName))
{
ctrl = page.FindControl(ctrlName);
}
return ctrl;
}
ちなみに「RegisterStartupScript」関数は.NETのバージョンによって書き方や挙動が違う時があるので、気を付けましょう。

