ASP.Net C# Маршрутизация; HttpHandler; и HttpModule не работает
У меня довольно много проблем с пользовательскими расширениями и перехватом существующих обработчиков.
Что я пытаюсь сделать
Основываясь на постоянных параметрах, я бы хотел, чтобы все "виртуальные" расширения обрабатывались наборами обработчиков. Все страницы создаются динамически, и на сайте не существует реальных файлов. Сайт заполняет контент, формирует вывод 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.
Спасибо за любые предложения о том, как решить эту проблему. Майк
1 ответ
Необходимо настроить веб-сайт в 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
Ближе к концу статьи автор дал, как добавить карту сценария подстановочного знака