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/
и перейти на правильную страницу.
Какую ужасную очевидную ошибку новичка я делаю?
Ответы
Ответ 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;
}
}
Таким образом, обратное сопоставление маршрутов никогда не выбирает этот маршрут для любого действия. Работает как шарм