Маршрутизация .GIF в одну сторону, остальная часть сайта MVC 4 в другую

Я просмотрел тысячи вопросов и блогов, но до сих пор не до конца понимаю прокладку плотин!

Как и в блог Скотта Хансельмана, я пытаюсь направить определенный вызов в .GIF в пользовательский HttpHandler, в то время как остальная часть сайта MVC4 ведет себя нормально. Я прошёл 90% пути.

Итак, в моем RouteConfig у меня есть

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.Add("AnalyticsRoute", new Route("analytics/a.gif", new AnalyticsRouteHandler()));
    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    routes.RouteExistingFiles = true;
}

и в моем web.config у меня есть

<handlers>
  ...
  <add name="analytics" verb="*" path="analytics/a.gif" type="Lms.Analytics.AnalyticsHandler, Lms.Analytics" preCondition="managedHandler" />
</handlers>

Таким образом, http://mysite.com/analytics/a.gif маршрутизируется правильно и все доволен, однако все мои ActionLinks разрешаются как http://mysite.com/analytics/a.gif?action=Index&controller=Category

Если я изменю порядок в RouteConfig, т.е.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    routes.Add("AnalyticsRoute", new Route("analytics/a.gif", new AnalyticsRouteHandler()));
    routes.RouteExistingFiles = true;
}

Все ссылки прекрасно разрешаются, но вызов http://mysite.com/analytics/a.gif приводит к ошибке 404?

Должно быть, я делаю что-то глупое и просто не вижу этого?!

заранее спасибо


person Martyn    schedule 12.06.2013    source источник


Ответы (3)


Наконец, наткнувшись на подобный пост, я взломал его. Сообщение было https://stackoverflow.com/questions/15261346/why-is-the-httphandler-not-running

Вам нужно игнорировать путь к файлу, который вы хотите обработать HttpHandler.

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.IgnoreRoute("analytics/a.gif");
        routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
        routes.RouteExistingFiles = true;
    }

Проблема заключалась в том, что когда я добавил web.config и удалил Route.Add, я получил 404. Я думаю, что механизм маршрутизации перенаправил обработчик.

person Martyn    schedule 13.06.2013

Что вам нужно сделать, так это создать свой собственный класс Route.

В этом классе вы должны переопределить метод GetVirtualPath (на MSDN), который проверит данные маршрута и сгенерирует правильный URL-адрес. Реализуйте его так, чтобы он возвращал null, если ваш специальный URL-адрес отсутствует в предоставленном RequestContext.

Что происходит сейчас в вашем приложении, так это то, что вы используете стандартный класс Route, который обрабатывает контроллер и действие в словаре RouteValue как параметры переполнения, поэтому они добавляются к созданному URL-адресу.

Когда вы добавляете маршрут в коллекцию маршрутов, используйте свой собственный класс вместо класса Route по умолчанию.

Дополнительные пояснения: когда вы используете любой метод, например Url.Action, для создания URL-адреса, вызывается RouteCollection.GetVirtualPath. И этот метод вызывает GetVirtualPath каждого зарегистрированного Route, пока один из них не вернет значение, отличное от нуля (строка URL). Поскольку вы не предоставляете свой собственный класс Route, используется «стандартный» класс Route, который возвращает нежелательный URL-адрес. Если вы создадите свой собственный класс Route с собственной реализацией GetVirtualPath, вы вернете желаемый URL-адрес.

person JotaBe    schedule 12.06.2013
comment
Хм, это, возможно, тоже сработало, но это был не тот путь, по которому я хотел пойти. Я был уверен, что с этим можно справиться в HttpHandlers. Извините, я не пробовал и решил это другим способом. - person Martyn; 13.06.2013
comment
как ты это решил? Вы должны поделиться своим решением, чтобы мы все могли его увидеть, и отметить его как правильное (я думаю, что вы сможете сделать через 2 дня). - person JotaBe; 13.06.2013

Согласно статье Хансельмана, вы не хотите добавлять маршрут для своего изображения, вы просто хотите настроить обработчик в файле web.config. Пробовали ли вы удалить свой AnalyticsRoute и посмотреть, работает ли он? Вам также может понадобиться добавить маршрут игнорирования, чтобы MVC не пытался обработать запрос.

Я не использовал его, но слышал об RouteMagic. , написанный Филом Хааком, отлично подходит для решения проблем с маршрутами.

person Brian Ball    schedule 12.06.2013
comment
Это не то, что я получил из статьи Хассельмана, я понял, что вы можете обойти это, используя runAllManagedModulesForAllRequests=false. Цитата: Помните, что HttpHandlers нацелены на определенный путь, файл или подстановочный знак, а HttpModules всегда наблюдают. Почему бы не использовать HttpHandler напрямую, подключить его на уровне web.config и установить runAllManagedModulesForAllRequests=false? Он нигде не упоминал, что делать с Route.Add. Я пытался удалить его, но получил только 404. Спасибо в любом случае. - person Martyn; 13.06.2013