Хорошо, это странно. Я создал простой пример сайта, чтобы продемонстрировать проблему. В ней у меня есть страница 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;
}
}
Опять же, это всего лишь демонстрация, но суть в том, что я обращаюсь к запросу, чтобы получить значение из строки запроса. Если я запускаю это в Кассини, все работает нормально. Однако, когда я запускаю это в IIS, это то, что происходит. Когда я запускаю сайт по адресу:
http://mysamplesite.dev/
и затем нажмите на кнопку, ничего не происходит. Страница просто перезагружается, но мой обработчик события для кнопки никогда не вызывается, и впоследствии текст метки никогда не обновляется. Однако, если я тогда запусту его на:
http://mysamplesite.dev/Default.aspx
и затем нажмите кнопку, все работает нормально, и мой обработчик событий вызывается!
После копания я изменил код в модуле так:
string text = "queryStringParam";
var value = context.Request.QueryString[text];
var boolValue = value == null;
Обратите внимание, здесь я обращаюсь к свойству QueryString напрямую, а не к контексту. Запрос. Когда я изменил его на это, он работает нормально, независимо от того, был ли у меня Default.aspx в URL?!
Следующий шаг, который я сделал, я посмотрел на 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;
И теперь он снова сломан! Короче говоря, просто получая доступ к коллекции Form по запросу в IHttpModule, я каким-то образом облажаю PostBack, и событие никогда не запускается.
У кого-нибудь есть идеи, почему это происходит? Я в большей степени парень из ASP.Net MVC, я не знаю ASP.Net и всех тех мелочей, которые он тянет за кулисами, достаточно хорошо, чтобы действительно понять, почему это происходит.