Файлы журнала 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).