ここでは ASP.NET の Web アプリケーションで Windows フォームアプリケーションのようなメッセージボックス制御を行うサンプルを掲載しています。
スポンサーリンク
ここで説明するメッセージボックスの制御には、Javascript を使用してポストバックを行っています。Javascript からフォームに対してサブミット ( ポストバック ) しているだけですので技術的に難しいことはありません。
今回は、以下のような一般的(?)な状況を例に考えることとします。
- 複数の入力項目を持つWebフォームで登録ボタンクリックでデータベースへ登録する
- 入力された情報がデータベース上に存在しない場合はそのまま登録する
- 入力された情報が既にデータベース上に存在すれば確認ダイアログを表示する
- OKボタンがクリックされた場合にのみ、その情報を上書きし、キャンセルボタンの場合は何もしない
Windows アプリケーションでは容易ですが、ASP.NET のような Web アプリではサーバとブラウザでそれぞれ実行順序を制御する必要があるので、悩むことも多いです。
[ ポイント ]
- データベースへの問い合わせはWebサーバで行う
- 確認ダイアログはブラウザ上で出力させる
- JavaScript からポストバックを行う
メッセージボックス制御サンプル(枠組のみ)
メッセージボックス制御のサンプルコードになります。なお、データベースへの登録処理などは本題ではありませんので記述していません。詳細はサンプルコード中のコメントを参照ください。
ASPX
<form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" Text="Button" /> </div> </form>
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If IsPostBack Then 'Javascriptからのsubmitはポストバックとして認識される ' 上書きする(OK)ボタンがクリックされた場合 Dim update As String = Page.Request.QueryString.Get("update") If (update = "true") Then '---------------------------------------------- ' TODO:ここで、データを上書きする処理を行う '---------------------------------------------- '(後始末) ' 次のポストバックでこのルートを通らないようにするために ' アップデートのために追加したGET パラメータ(update)をaction属性から除去する Dim formid As String = Me.Form.ClientID Dim cScript As String = formid + ".action = ""Default.aspx"";" 'JavaScriptの埋め込み(画面表示前に実行させる) ClientScript.RegisterClientScriptBlock(Me.GetType(), "clientscript", cScript, True) End If End If End Sub Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Dim confirm As Boolean '-------------------------------------------------------- ' TODO:ここにデータベースに存在するか確認する処理を記述する '-------------------------------------------------------- If (True) Then ' 確認ダイアログを出力させる confirm = True Else '確認ダイアログを出力させない confirm = False End If 'マスターページを使っている場合、formタグのidがaspnetFormとなるので、 '確実に取得するためには、Form.ClientIDプロパティからIDを取得する Dim formid As String = Me.Form.ClientID If (confirm) Then ' 確認ダイアログを出力するスクリプト ' POST先は自分自身(Default.aspx) Dim sScript As String = "if(confirm(""上書きしますか?"")){ " + _ formid + ".method = ""post"";" + _ formid + ".action = ""Default.aspx?update=true"";" + _ formid + ".submit();" + _ "}" 'JavaScriptの埋め込み ClientScript.RegisterStartupScript(Me.GetType(), "startup", sScript, True) ' ClientScript.RegisterStartupScriptメソッドで登録した場合、ブラウザでの描画完了後に ' 登録したJavaScriptが実行される ' ' ここでは、OKボタンが押されたことをGETパラメーター(update)で通知する Else '-------------------------------------------------------- ' TODO:ここに、データを登録する処理を記述する '-------------------------------------------------------- End If End Sub
C#
protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // Javascriptからのsubmitはポストバックとして認識される // ここで、GETパラメーター(update)がTrueの場合には、フォーム上のデータを // データベース上に上書きする処理を記述する // 上書きする(OK)ボタンがクリックされた場合 string update = Page.Request.QueryString.Get("update"); if (update == "true") { //------------------------------------------------- // TODO:ここで、データを上書きする処理を行う //------------------------------------------------- //(後始末) // 次のポストバックでこのルートを通らないようにするために // アップデートのために追加したGET パラメータ(update)をaction属性から除去する string formid = this.Form.ClientID; string cScript = formid + ".action = \"Default.aspx\";"; // JavaScriptの埋め込み(画面表示前に実行させる) ClientScript.RegisterClientScriptBlock(this.GetType(), "clientscript", cScript, true); } } } protected void Button1_Click(object sender, EventArgs e) { Boolean confirm; //------------------------------------------------- // TODO:ここにデータベースに存在するか確認する処理を記述する //------------------------------------------------- if (true) { // 確認ダイアログを出力させる confirm = true; } else { // 確認ダイアログを出力させない confirm = false; } // マスターページを使っている場合、formタグのidがaspnetFormとなるので、 // 確実に取得するためには、Form.ClientIDプロパティからIDを取得する string formid = this.Form.ClientID; if (confirm) { // 確認ダイアログを出力するスクリプト string sScript = "if(confirm(\"上書きしますか?\")){ " + formid + ".method = \"post\";" + formid + ".action = \"Default.aspx?update=true\";" + formid + ".submit();" + "}else{" + "" + "}"; // JavaScriptの埋め込み ClientScript.RegisterStartupScript(this.GetType(), "startup", sScript, true); // ClientScript.RegisterStartupScriptメソッドで登録した場合、ブラウザでの描画完了後に // 登録したJavaScriptが実行される // // OKがクリックされるとGETパラメーター(update)を付けて、ポストバックする } else { //------------------------------------------------- // TODO:ここに、データを登録する処理を記述する //------------------------------------------------- } }
F5 などで再表示を行った場合の問題点
今回のサンプルでは上書きするかの判断を GET パラメータ ( update ) で行っていますが、 Page_Load イベントで上書き処理を行った状態で再表示 ( F5 ) を行うと、再度上書き処理が行われてしまいます ( GET パラメーターも再度送られる )。
対応方法は色々あると思いますが、解決手段の1つとして、Page_Load イベントで更新登録したあとでClientScript.RegisterClientScriptBlock で スクリプトを埋め込む代わりに、Response.Redirect ( URL には Get パラメーターをつけない ) で自分自身にリダイレクトさせる方法があります。クライアントとブラウザ間でやり取りの回数が増えますが、簡単な対処方法です。
ポストバックにしたくないとき
今回は Javascript からポストバックするようにしましたが、” キャンセル ” が選択されたときに、単にページ遷移する場合には form.submit ではなく、location.href を使用できます。
location.href = “Default.aspx”;
ASP.NET とは関係なく、Javascript の話です