У меня есть веб-сайт, определенный в определениях сайтов Sitecore. Путь к нему /localhost/mysite/home
. И это работает.
Мне нужно создать собственный контроллер для отправки форм с API в обход Sitecore. Итак, у меня есть FormsController
(унаследованный от контроллера MVC) с действием под названием «Тест», не имеющим параметров.
Я определил маршрут в конвейере инициализации следующим образом:
public class Initialize
{
public void Process(PipelineArgs args)
{
MapRoutes();
GlassMapperSc.Start();
}
private void MapRoutes()
{
RouteTable.Routes.MapRoute(
"Forms.Test",
"forms/test",
new
{
controller = "FormsController",
action = "Test"
},
new[] { "Forms.Controller.Namespace" });
}
}
Маршрут правильно добавлен в таблицу маршрутов, и он там, когда я его отлаживаю. Теперь, когда я пытаюсь вызвать метод test, маршрут не найден, и отладчик не достигает точки останова в действии.
Пробую разные маршруты:
/localhost/mysite/home/forms/test
/localhost/forms/test
(веб-сайт по умолчанию)
Но пока безуспешно.
---- ОБНОВЛЕНИЕ ---
Заглянув глубже, я заметил, что что-то не так с поведением Sitecore. Предполагается, что процессор TransferRoutedRequest
прервет конвейер httpRequestBegin
, вернув управление MVC, в случае, если элемент контекста равен нулю (упрощение). Это происходит после некоторых проверок, среди которых есть проверка данных RoutTable. Но вызов RouteTable.Routes.GetRouteData
всегда возвращает null, что заставляет процессор возвращаться без прерывания конвейера. Я переопределил его, чтобы он правильно прервал конвейер, но все же, даже если он вызывает метод args.AbortPipeline()
, конвейер не прерывается и маршрут не разрешается.
так выглядел оригинал TransferRoutedRequest
:
public class TransferRoutedRequest : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull((object) args, "args");
RouteData routeData = RouteTable.Routes.GetRouteData((HttpContextBase) new HttpContextWrapper(HttpContext.Current));
if (routeData == null)
return;
RouteValueDictionary routeValueDictionary = ObjectExtensions.ValueOrDefault<Route, RouteValueDictionary>(routeData.Route as Route, (Func<Route, RouteValueDictionary>) (r => r.Defaults));
if (routeValueDictionary != null && routeValueDictionary.ContainsKey("scIsFallThrough"))
return;
args.AbortPipeline();
}
}
и вот как я это отменил:
public class TransferRoutedRequest : global::Sitecore.Mvc.Pipelines.HttpRequest.TransferRoutedRequest
{
public override void Process(HttpRequestArgs args)
{
if (Context.Item == null || Context.Item.Visualization.Layout == null)
args.AbortPipeline();
else
base.Process(args);
}
}