前回のつづき
簡単な事だ。単純に、ビュー状態が最新でなければポストバック扱いではなく、初期ロード扱いにすればよい。例えば以下のように書きたい(Default.aspx.cs に書かれているコードとする)。
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack && !IsValidViewState)
{
Response.Redirect("Default.aspx");
}
}
IsValidViewState の実装は以下の様になる。
private bool IsValidViewState
{
get
{
return
(long)(ViewState["_Default_ViewState"]) ==
(long)(Session["_Default_ViewState"]);
}
}
ViewState と Session に同一値を入れておく。例えば以下の様に。
private void SetValidViewState()
{
long ticks = DateTime.Now.Ticks;
ViewState["_Default_ViewState"] = ticks;
Session["_Default_ViewState"] = ticks;
}
SetValidViewState() はパイプラインの最後の方のどこかに呼び出しておくと良いだろう。Page_Load() の最後でも良いと思う。
ここまで話を引張って、これは拍子抜けだと思うかもしれないが、要は「そのポストバックは期待しているものか」の判断をユーザーコードに仕込んでおく。自分自身にリダイレクトしている理由は、完全に初期ロード扱いしたいからだ。こうしておかないと、ポストバックを発生させたボタンクリックイベント等、各イベントハンドラが実行されてしまう。
もう一度言うが、クライアント処理は一切信頼してはいけない。状態管理はサーバー側だけで行う。
最後に、全てにこのような処理は入れないようにしてほしい。どのような状況にも対応できる完璧なセオリーなど存在しない。