ASP.Net C # Маршрутизация; HttpHandler; и HttpModule не работает - PullRequest
2 голосов
/ 23 ноября 2011

У меня довольно много проблем с пользовательскими расширениями и перехватом существующих обработчиков.

Что я пытаюсь сделать

Исходя из постоянных параметров, я хотел бывсе «виртуальные» расширения должны обрабатываться обработчиками множеств.Все страницы создаются динамически, и на сайте не существует реальных файлов.Сайт заполняет контент, формирует вывод html и возвращает его как веб-результат.Это необходимо, так как я устанавливаю толстую / тонкую связь между двумя серверами.Тонкий сервер просто передает запрос на толстый сервер - где запрос обрабатывается и ответ отправляется обратно по линии.Проект предназначен для динамической многодоменной системы управления контентом.Тонкий сервер может быть не совместим с .net (следовательно, внешний запрос), но будет оптимизирован .net (следовательно, потребуется обработчик).

Проблема

Я хочу перенаправить существующие расширения - aspx;PHP;HTML.Я добился этого в своей локальной среде, используя собственный HttpModule, который устанавливает соответствующий обработчик.Я исследовал установку тега в config, но расширения перенаправляются с использованием сохраняющихся динамических правил.

Как уже упоминалось, это решение работает на localhost.При загрузке расширения .Net обрабатываются модулем корректно, но любые пользовательские расширения или расширения, отличные от .NET, возвращают ошибку 404.

В поисках альтернативы я экспериментировал с маршрутизацией в Global, но это нелибо работать.

Я также пытался использовать для регистрации пользовательских расширений ... но каждое встречается с тем же результатом - 404 не найдено.


Попытка глобальной маршрутизации:

public class Global : System.Web.HttpApplication
{

    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterRoutes(RouteCollection routes)
    {

        routes.Add(new Route("{action}.sqs", new SqlRequestHandler()));
    }

.Config (для попытки обработчика и модуля)

    <system.web>
      <compilation debug="true" targetFramework="4.0" />
      <httpRuntime requestValidationMode="2.0" />
      <customErrors mode="Off"/>

      <httpHandlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" />
      </httpHandlers>

      <httpModules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </httpModules>
  </system.web>

  <system.webServer>   
      <modules runAllManagedModulesForAllRequests="true" />
      <modules>
        <add name="SisBerCMS" type="CmsMapper.VirtualModule, CmsMapper" />
      </modules>

      <handlers>
        <add path="*.sqs" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqsHandler" />
        <add path="*.sql" verb="*" type="CmsMapper.VirtualHandler, CmsMapper" name="sqlHandler" />
      </handlers>
  </system.webServer>

Пользовательский модуль (CmsMapper.VirtualModule)

    if (extentionMap != null)
    {
        // note that extentionMap.ExtentionType is a predetermined enum
        switch (extentionMap.ExtentionType)
        {
            // If the extention is banned then pass back a generic message
            case ExtentionType.Banned:
                this.WriteTextResponce("Invalid extention detected:" + extentionMap.Extention);
                break;

            // Remap .Ajax requests to the ajax handler
            case ExtentionType.Ajax:
                this._app.Context.RemapHandler(new AjaxHandler());
                break;

            // Remap session query or sql requests to the sql handler
            case ExtentionType.SessionQuery:
                this._app.Context.RemapHandler(new SqlRequestHandler());
                break;

            // if the extention is not ignored, re map to the virtual page handler
            default:

                bool isManagementServer = this._app.Context.Request.Url.Authority != VirtualModule.RESPONSE_SERVER;
                bool isPostRequest = !String.IsNullOrEmpty(this._app.Context.Request.Form[HtmlRequest.RequestOrigin]);
                bool isGetRequest = !String.IsNullOrEmpty(this._app.Context.Request.QueryString[HtmlRequest.RequestOrigin]);
                bool isIgnored = extentionMap.ExtentionType == ExtentionType.Ignore;

                if ((isPostRequest || isGetRequest) && !isIgnored)
                {
                    this._app.Context.RemapHandler(new VirtualHandler());
                }
                else
                {
                    this._app.Context.RemapHandler(new ExternalRequestHandler());
                }

                break;
        }
    }

Все обработчики довольно стандартны и реализуют следующее:

public class SqlRequestHandler : IHttpHandler, IRequiresSessionState, IRouteHandler

Опять же, предпочтительный метод - HttpModule - работает на моем локальном хосте.Это может быть проблема конфигурации сервера (в этом случае я ищу обходной путь), но тот факт, что обрабатываются расширения .net, странный, поскольку это подразумевает, что проблемы со средним доверием не должны применяться, однако проблемыЧто касается обработки расширений на сервере, может иметь приоритет над приложением .net.

Сервер является общим хостингом (поэтому я не могу изменить файлы machine.config), это IIS6 с использованием 4.0.

Спасибо за любые предложения о том, как решить эту проблему.Mike

1 Ответ

0 голосов
/ 23 ноября 2011

Необходимо настроить веб-сайт в IIS 6.0 для маршрутизации всех расширений (включая пути без расширений, известные как сопоставление расширений подстановочных знаков ) в dll ASP.NET ISAPI (и отключить проверку наличия файла).

Конечно, вы можете делать это выборочно только для тех расширений, которые вы хотите маршрутизировать через код ASP.NET. Но отображение подстановочных знаков будет более полезным, если у вас нет предопределенного набора расширений.

В отсутствие таких сопоставлений IIS не будет пересылать запросы на неизвестные расширения в ASP.NET (и код маршрутизации даже не появится), скорее IIS передаст расширение обработчику по умолчанию (статический файл), который будет выдавать 404, если файла нет.

См. Эту статью, в которой описаны следующие действия (для ASP.NET MVC, но то же самое относится и к вашему случаю): http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
В конце статьи автор дал, как добавить карту сценария с подстановочными знаками

...