Файлы журнала IIS7, RewritePath и IIS
Я использую Context.RewritePath() в приложении ASP.NET 3.5, работающем на IIS7.
Я делаю это в приложении BeginRequest, и все работает с файлом.
Запросы на/спорт правильно переписаны по умолчанию .aspx? id = 1 и т.д.
Проблема в том, что в моем журнале IIS я вижу запросы GET для /Default.aspx?id=1, а не для /sports.
Этот тип кода отлично работал под IIS6.
Использование Microsoft Rewrite не является вариантом, из-за некоторой бизнес-логики, которая должна быть реализована.
Спасибо.
ИЗМЕНИТЬ:
Кажется, что мой обработчик слишком рано в конвейере, но если я переведу логику на более поздний случай, чем вся переписывающая вещь не работает (слишком поздно, StaticFileHandler берет мой запрос).
Я googled и googled, спросил вокруг, не могу поверить, что никто не имеет этой проблемы?
EDIT:
Хлоп! Вот что я нашел на форуме IIS:
"Это связано с тем, что в интегрированном режиме IIS и asp.net совместно используют общий конвейер, а RewritePath теперь рассматривается IIS, а в IIS6 его даже не видел IIS - вы можете обойти это, используя классический режим, который будет вести себя как IIS6."
Окончательное обновление. Пожалуйста, посмотрите мой ответ ниже, я обновил его с результатами после более чем года производства окружающая среда.
Ответы
Ответ 1
После некоторых исследований я наконец нашел решение проблемы.
Я заменил вызовы на метод Context.RewritePath() с новым (введенным в ASP.NET 3.5) способом Context.Server.TransferRequest().
Теперь это кажется очевидным, но не событие, о котором подумал старший инженер Dev Engine в команде IIS Core.
Я тестировал его для сеанса, проверки подлинности, обратной передачи, запроса,... проблем и не нашел.
Tommorow Я развожу это изменение на сайт с очень высоким трафиком, и мы скоро узнаем, как он работает.:)
Я вернусь с обновлением.
Обновление: решение по-прежнему не полностью на моих производственных серверах, но оно протестировано, и оно работает, и насколько я могу судить до сих пор, это решение моей проблемы. Если я найду что-нибудь еще в производстве, я опубликую обновление.
Последнее обновление: У меня есть это решение в производстве уже более года, и оно оказалось неплохим и стабильным решением без проблем.
Ответ 2
Вы можете установить путь к исходному значению после обработки запроса, но до того, как модуль протоколирования IIS будет записывать запись журнала.
Например, этот модуль перезаписывает путь на BeginRequest
, а затем возвращает его обратно к исходному значению в EndRequest
. Когда этот модуль используется, исходный путь отображается в файле журнала IIS:
public class RewriteModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += OnBeginRequest;
context.EndRequest += OnEndRequest;
}
static void OnBeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
app.Context.Items["OriginalPath"] = app.Context.Request.Path;
app.Context.RewritePath("Default.aspx?id=1");
}
static void OnEndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var originalPath = app.Context.Items["OriginalPath"] as string;
if (originalPath != null)
{
app.Context.RewritePath(originalPath);
}
}
public void Dispose()
{
}
}
Ответ 3
У меня была точно такая же проблема. Один из способов - использовать Server.Transfer вместо Context.RewritePath. Server.Transfer не перезапускает весь жизненный цикл страницы, поэтому исходный URL-адрес все равно будет регистрироваться. Обязательно передайте "true" для параметра "preserveForm", чтобы коллекции QueryString и Form были доступны на второй странице.
Ответ 4
Старый вопрос, но я обнаружил, что не столкнулся с вашей проблемой, когда я сделал следующее:
a) Правило перезаписи в web.config для направления всех запросов на /default.aspx, например:
<rule name="all" patternSyntax="Wildcard" stopProcessing="true">
<match url="*"/>
<action type="Rewrite" url="/default.aspx"/>
</rule>
b) Вызвал RewritePath в событии Page_PreInit
default.aspx, чтобы переписать URL-адрес и строку запроса как то, что было передано в запросе (т.е. место, которое не существует).
Например, я запрашиваю "/somepage/? x = y" (который не существует).
a) Правило Web.config сопоставляет его с /default.aspx
b) Page_PreInit переписывает его обратно в "/somepage/? x = y".
Результатом этого в IIS 7 (Express и production) является то, что журнал сервера отражает "/somepage" для заглушки и "x = y" для запроса, и все свойства объекта "Запрос" отражают запрошенное (несуществующее ) URL (это то, что я хотел).
Единственный странный эффект: в IIS Express элемент журнала записывается дважды. Однако этого не происходит в производстве (Windows Server 2008 R2).