質問者
asp.net&ajaxで開発中でresponse.write()でエラー

質問
-
になるのですが、具体的には、UpdatePanelないのtextboxが空欄でボタンを押した時にポップアップを出そうとしています。以下です。
button_click(object sender, eventargs e)
{
string script = "<script type='text/javascript>";
script += "alert('enter name')";
script += "</script>";
Response.Write(script);
}
とすると、エラーメッセージが以下の様になります。
Sys.WebForms.PageRequestManagerParserErrorException
試しに、UpdatePanelの外で試すと正常に表示されます。そこで、このエラーをキーワードに調べますと、USのフォーラムで自分の状況に近い事は載っていましたが、Response.Writeを使うとおかしくなるような事が書いてあったのですが、詳細を知っている方がいたら教えてください。
ajaxをいじってまもないので、基本的な事を勉強中です。
すべての返信
-
調べられた通りです。簡単に言えば、Ajaxは裏で非同期に特別なフォーマットでサーバーとクライアント間で通信していますが、Response.Writeをすることにより、その特別なフォーマットにゴミが入るためです。以下が詳しいです。
Sys.WebForms.PageRequestManagerParserErrorException - what it is and how to avoid it
-
このような場合は、クライアントスクリプトで PageRequestManager を使って非同期ポストバックのクライアントイベントハンドラで処理します。
●Default.aspx
Code Snippet<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<Scripts>
<asp:ScriptReference Path="Script.js" />
</Scripts>
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>●Script.js
Code Snippet// Sys.Application イベントの追加
Sys.Application.add_init(AppInit);
// Sys.Application.init イベントハンドラ
function AppInit(sender)
{
// PageRequestManagerインスタンスの取得
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (!prm.get_isInAsyncPostBack())
{
// 非同期ポストバックの各イベントハンドラの設定
prm.add_initializeRequest(InitializeRequest);
}
}
// 非同期ポストバックの初期化(initializeRequest)イベントハンドラ
function InitializeRequest(sender, args)
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (!prm.get_isInAsyncPostBack() &&
args.get_postBackElement().id == "Button1" &&
$get("TextBox1").value == "")
{
args.set_cancel(true);
alert("テキストを入力してください");
}
}
これで、お望みの動作になるかと。
あとは、RequiredFieldValidator を使うか、もしくは AJAX Control Toolkit の
ValidatorCallout エクステンダ
http://ajax.asp.net/ajaxtoolkit/ValidatorCallout/ValidatorCallout.aspx
などを使う方法もあります。
-
chack - Akira Inoue さんからの引用 このような場合は、クライアントスクリプトで PageRequestManager を使って非同期ポストバックのクライアントイベントハンドラで処理します。
これで、お望みの動作になるかと。
~(中略)~
あとは、RequiredFieldValidator を使うか、もしくは AJAX Control Toolkit の
ValidatorCallout エクステンダ
http://ajax.asp.net/ajaxtoolkit/ValidatorCallout/ValidatorCallout.aspx
などを使う方法もあります。
なるほど。大変勉強になります。あと、動作確認が取れている方法として以下がありますが、こういうことをやってもいいのか今のところ確信が持てていません。どうなんでしょう?
ScriptManager.RegisterClientScriptBlock(this.UpdatePanel1, this.GetType(), "enterName", "alert('enter name');", true);
-
つまりは、こんな感じでサーバ側で処理させるわけですよね。
Code Snippetprotected void Button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(TextBox1.Text))
ScriptManager.RegisterClientScriptBlock(this.UpdatePanel1, this.GetType(),
"enterName", "alert('enter name');", true);
else
Label1.Text = TextBox1.Text;
}
メリットとしては、サーバ側で TextBox1 の内容によって、例えば DB と照合したり、他の Web サービスと連携したりすることもできて、その結果によってスクリプトの内容を柔軟に変えることもできますから、状況によってはこの方法も使えると思いますよ。
ただ、非同期ポストバックによって必ずサーバ側との通信が発生するわけですから、サーバの負荷などを考慮すると、クライアントサイドで済ませられることは、クライアントで処理したほうが良い訳です。
(特に AJAX アプリケーションでは、うまく設計しないとサーバ負荷やトラフィックが大きくなりがちですし・・・)
今回の場合は、TextBox1 の値が Empty かどうか?の条件ですから、出来ればクライアントスクリプトで PageRequestManager を使った方法をお勧めします。
その他の場合は、検証内容やサーバ負荷、トラフィックなどを考慮して使い分けるのがベストかと。
-
chack - Akira Inoue さんからの引用 つまりは、こんな感じでサーバ側で処理させるわけですよね。
その通りです。
chack - Akira Inoue さんからの引用 メリットとしては、サーバ側で TextBox1 の内容によって、例えば DB と照合したり、他の Web サービスと連携したりすることもできて、その結果によってスクリプトの内容を柔軟に変えることもできますから、状況によってはこの方法も使えると思いますよ。
ありがとうございます。Ajaxはまだ本格的に取り組んだことがないので、どうもこのあたりのレンダリングの関係が今一歩不安なんです。やっていいことと悪いことが今一歩整理できていません。下期には本格的にAjaxを扱おうと思っていますので、少しずつですが知識を仕入れているところです。
chack - Akira Inoue さんからの引用 ただ、非同期ポストバックによって必ずサーバ側との通信が発生するわけですから、サーバの負荷などを考慮すると、クライアントサイドで済ませられることは、クライアントで処理したほうが良い訳です。
(特に AJAX アプリケーションでは、うまく設計しないとサーバ負荷やトラフィックが大きくなりがちですし・・・)
なるほど。言われてみれば確かにそうですね。Ajaxなのでクライアント処理が基本ということをまず頭に置いて、そこから応用していくのがいいわけですね。Ajaxなので下手にサーバー側でレンダリングを弄ってしまうと、おかしくなるんじゃないかというのが気になっていたので、少し方向性が見えてきた気がします。ありががとうございました。