Подтвердить что ты не робот

MVC2 Маршрутизация с помощью WCF ServiceRoute: Html.ActionLink рендеринг неправильных ссылок!

У меня есть служба WCF, которая живет бок о бок с веб-сайтом MVC2. Я бы хотел, чтобы мой URL-адрес службы выглядел следующим образом:

http://localhost/projdir/Service

Сайт MVC находится в зачаточном состоянии, поэтому он все еще имеет свои контроллеры и т.д.

Следующий код работает на первый взгляд в global.asax:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new ServiceRoute("Service", new ServiceHostFactory(), 
               typeof(MyService)));

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", 
              id = UrlParameter.Optional } // Parameter defaults
    );
}

Служба отображается только там, где я описывал и работает как рекламируемый. Отлично.

Однако я просто заметил, что упорядочение моего кода таким образом изменяет все мои ActionLink. Например, вкладка "О программе" на сайте MVC теперь выглядит следующим образом:

http://localhost/projdir/Service?action=About&controller=Home

Это явно неверно (это должно быть http://localhost/projdir/Home/About/).

Если я перемещаю добавление ServiceRoute ниже стандартного вызова MapRoute(), тогда я получаю недостающую ошибку контроллера. (На самом деле я получаю сообщение об ошибке "StructureMapControllerFactory не возвратил экземпляр контроллера", потому что я подключен к StructureMap, duh, это не контроллер для начала.)

Интересно, что это только влияет на вывод Html.ActionLink(). Я могу вручную ввести http://localhost/projdir/Home/About/ и перейти на правильную страницу.

Какую ужасную очевидную ошибку новичка я делаю?

4b9b3361

Ответ 1

Попробуйте переместить маршрут службы после маршрута MVC. Но чтобы избежать ошибки "пропавшего контроллера", которую вы получили до этого, добавьте маршрут MVC с Ограничение маршрута. Эти ограничения маршрута могут быть Regex - в основном вы хотите, чтобы ваше ограничение маршрута было любым контроллером, который не является "Сервисом". Когда запрашивается запрос "Сервис", он провалится и его сервисный маршрут WCF.

Ответ 2

Я решил с этим:

     routes.MapRoute(
             "Default", // Route name
             "{controller}/{action}/{id}", // URL with parameters
             new { controller = "Home", action = "Index", id = UrlParameter.Optional },
             new { controller = "^(?!api).*" }
        );
        routes.Add(new ServiceRoute("api", new DataServiceHostFactory(), typeof(dwService)));

Я надеюсь, что это хорошо для вас.

Ответ 3

Другим решением является наследование ServiceRoute и переопределение метода GetVirtualPath для возврата null, как описано здесь

public class AppServiceRoute : ServiceRoute
{
    public AppServiceRoute(string routePrefix, ServiceHostFactoryBase serviceHostFactory, Type serviceType)
        : base(routePrefix, serviceHostFactory, serviceType)
    {
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

Таким образом, обратное сопоставление маршрутов никогда не выбирает этот маршрут для любого действия. Работает как шарм