Не удалось сопоставить HttpHandler с подстановочным отображением пути/*

Итак, я пытался сопоставить http-модуль с подпункта сайта MVC3. Это должно быть довольно просто, как я понимаю, но он не работает. Модуль настроен так:

<handlers>
  <add name="Nancy" path="api/*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
</handlers>

Соответствующий раздел также существует для iis6, поэтому я могу запустить его под webdev.webserver. Однако, тестируя как развертывание на моем локальном iis7 (под Win7), так и с webdev.webserver, только /api фактически вызывает обработчик. Если я вызываю/api/{ничего}, он просто возвращает 404.

Я уверен, что я просто "делаю это неправильно (tm)", но любая помощь будет оценена.

Примечание. Я также пробовал пару других конфигураций, включая использование тега и создание папки /api, а также добавление файла web.config в эту папку с полным шаблоном.

Ответ 1

URLRoutingModule-4.0 - это обработчик catch, указанный перед вашим обработчиком nancy. Это, таким образом, вступит в игру до того, как ваш обработчик когда-либо попадет. Вы можете удалить обработчиков, добавив их и добавить их обратно так:

<handlers>
    <remove name="BlockViewHandler" />
    <remove name="UrlRoutingModule-4.0" />
    <add verb="*" path="robots.txt" name="robots" type="System.Web.StaticFileHandler"/>
    ... custom handlers here
    <add name="Nancy" path="api/*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
    ... now add back UrlRoutingModule and BlockViewHandler
    <add path="*" verb="*" name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" preCondition="managedHandler" />
    <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> 
</handlers>

Вы можете увидеть порядок обработчика в IIS7 под Handler Mappings select View Ordered List и он будет перечислять порядок, в котором он загружает верхние (первые) обработчики вниз (последние).

Вам может понадобиться вторая Web.config в вашей папке /api

<?xml version="1.0"?>
<configuration>
    <system.web>
      <httpHandlers>
        <clear />
        <add name="Nancy" path="*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
      </httpHandlers>
    </system.web>
</configuration>

Аналогично, это то, что я обычно делаю для контента "/static" на веб-сайтах. Я не узнал, как обойти необходимость в секундах web.config.

ИЗМЕНИТЬ

Мне было трудно понять это, когда мне приходилось, и, похоже, моя память не служила мне хорошо. Я не указываю обработчик path/* где-нибудь, вместо этого у меня есть это:

(только задание простых подстановочных знаков/полных путей для перемещения по UrlRouting)

<location path="." inheritInChildApplications="false">
    <system.webServer>
        <!--
        ml: in .NET 4.0 its now safe to remove  from the modules section.
        Make sure you have a *. mapping to a ExtensionLessUrl hanlder in IIS
        this should improve performance a tad albeit neglectable.

        see: http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-impacting-static-requests.aspx
        -->

        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="false" />
        <handlers>
            <remove name="BlockViewHandler" />
            <remove name="UrlRoutingModule-4.0" />
            <add verb="*" path="robots.txt" name="robots" type="System.Web.StaticFileHandler"/>
            .. Some company handlers i can't list 
            <add path="*" verb="*" name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" preCondition="managedHandler" />
            <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
        </handlers>
    </system.webServer>
</location>

Затем в моем /Content/web.config файле я установил следующее:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <clear />
            <add name="StaticFiles" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="None" />
        </handlers>
        <staticContent>
            <clientCache cacheControlMaxAge ="31.00:00:00" cacheControlMode="UseMaxAge" />
        </staticContent>
    </system.webServer>
</configuration>

Список моих обработчиков для /Content/ выглядит следующим образом:

Handler list

Что бы быть уверенным, что я могу быть чем-нибудь в /Content/, будет использоваться через StaticFileModule. Трюк здесь, кажется, указывает: inheritInChildApplications="false".

Ответ 2

Simple. Просто поставьте путь, не подстановочный знак.

<handlers>
  <add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
</handlers>

Это будет соответствовать:

/API/{ничего}

Ответ 3

Кажется, что UrlRoutingModule-4.0 больше проблем, чем того стоит. Вместо этого я просто сказал MVC3 игнорировать маршруты. Не идеальное решение, но пока у меня есть что-то, что работает лучше, мне придется придерживаться этого в RegisterRoutes:

routes.IgnoreRoute("api/{*route}");