わかりました、これは奇妙なものです。この問題を説明するために、簡単なサンプル サイトを作成しました。その中に、ボタンのある Default.aspx ページがあります。
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<p><asp:Button OnClick="ButtonClick" Text="Button" runat="server" />
</p>
<asp:Label ID="output" runat="server" />
</asp:Content>
コード ビハインドは、ボタン クリック時にラベル テキストを設定するだけです。
protected void ButtonClick(object sender, EventArgs e)
{
output.Text = "Button Click!!";
}
次に、リクエストごとに呼び出される IHttpModule を用意します。
public class SampleModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
if(application == null)
{
return;
}
HttpContext context = application.Context;
if(context == null)
{
return;
}
string text = "queryStringParam";
var value = context.Request[text];
var boolValue = value == null;
}
}
繰り返しますが、これは単なるデモですが、ここでのポイントは、クエリ文字列から値を取得するために Request にアクセスしていることです。これを Cassini で実行すると、すべて正常に動作します。ただし、IIS でこれを実行すると、これが発生します。次の場所でサイトを実行すると:
http://mysamplesite.dev/
ボタンをクリックしても何も起こりません。ページはリロードされるだけですが、ボタンのイベント ハンドラーが呼び出されず、その後、ラベル テキストが更新されません。ただし、次の場所で実行すると:
http://mysamplesite.dev/Default.aspx
ボタンをクリックすると、正常に動作し、イベント ハンドラーが呼び出されます。
いくつか掘り下げた後、モジュールのコードを次のように変更しました。
string text = "queryStringParam";
var value = context.Request.QueryString[text];
var boolValue = value == null;
ここでは、QueryString プロパティに直接アクセスしており、context.Request にはアクセスしていないことに注意してください。これに変更すると、URLにDefault.aspxがあったかどうかに関係なく正常に動作します?!
次に行ったステップは、Reflector を調べて、HttpRequest インデクサー プロパティのコードが実際に何を行っているかを確認することでした。
public string this[string key]
{
get
{
string str = this.QueryString[key];
if (str != null)
{
return str;
}
str = this.Form[key];
if (str != null)
{
return str;
}
HttpCookie cookie = this.Cookies[key];
if (cookie != null)
{
return cookie.Value;
}
str = this.ServerVariables[key];
if (str != null)
{
return str;
}
return null;
}
}
無害に思えますが、さまざまなコレクションをチェックするだけなので、それぞれを個別にチェックする必要はありません。それで、私は、それらの呼び出しのどれがそれを壊すのか疑問に思っています。次に、モジュールを次のように変更しました。
string text = "queryStringParam";
var value = context.Request.QueryString[text];
var boolValue = value == null;
var value2 = context.Request.Form[text];
var boolValue2 = value2 == null;
そして今また壊れた!つまり、IHttpModule の要求で Form コレクションにアクセスするだけで、どういうわけか PostBack が台無しになり、イベントが発生しなくなります。
なぜこれが起こっているのか誰にも分かりますか?私はどちらかというと ASP.Net MVC 派です。ASP.Net と、ASP.Net が舞台裏で引っ張るすべてのおしゃべりをよく知らないので、なぜこれが起こっているのかについての手がかりが得られます。