Маршрутизиране на .GIF в едната посока, на останалата част от сайта на MVC 4 в друга

Прегледах 1000 въпроси и блогове и все още не разбирам напълно маршрута на язовир!

По линия на блога на Скот Хензелман се опитвам да насоча определено повикване към .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. Предполагам, че механизмът за маршрутизиране надделяваше над Handler.

person Martyn    schedule 13.06.2013

Това, което трябва да направите, е да създадете свой собствен персонализиран Route клас.

В този клас трябва да замените метода GetVirtualPath (на MSDN), който ще прегледа данните за маршрута и ще генерира правилния Url. Приложете го така, че да връща null, ако вашият специален Url не е в предоставения RequestContext.

Това, което се случва сега във вашето приложение е, че използвате стандартния клас Route, който третира контролера и действието в речника RouteValue като параметри за препълване, така че те се добавят към създадения url.

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

Повече обяснение: когато използвате метод като Url.Action за създаване на Url, се извиква RouteCollection.GetVirtualPath. И този метод извиква GetVirtualPath на всеки регистриран Route, докато един от тях върне стойност, различна от null (низът 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

Според статията на Hanselman, вие не искате да добавите маршрут за вашето изображение, а просто искате да настроите манипулатора във вашия web.config. Опитахте ли да премахнете своя AnalyticsRoute и да видите дали работи? Може също да се наложи да добавите маршрут за игнориране, за да попречите на MVC да се опитва да обработи заявката.

Не съм го използвал, но съм чувал RouteMagic , написан от Фил Хаак, е страхотен в отстраняването на проблеми с маршрута.

person Brian Ball    schedule 12.06.2013
comment
Това не е, което разбрах от статията на Hasselmans, разбрах, че можете да се придвижите с помощта на runAllManagedModulesForAllRequests=false. Цитат: Не забравяйте, че HttpHandlers са насочени към конкретен път, файл или заместващ знак и HttpModules винаги наблюдават. Защо не използвате директно HttpHandler и не го включите на ниво web.config и не зададете runAllManagedModulesForAllRequests=false? Той никъде не спомена какво да прави с Route.Add. Опитах да го премахна, но получих само 404. Благодаря все пак. - person Martyn; 13.06.2013