Sitecore,自定义MVC控制器和路由

Hel*_*ser 3 c# routing sitecore sitecore7 asp.net-mvc-5

我在Sitecore的网站定义中定义了一个网站。路径是/localhost/mysite/home。而且有效。

我需要创建一个自定义控制器,以使用绕过Sitecore的API提交表单。因此,我FormsController(从MVC控制器继承)具有名为“ Test”的操作,不带任何参数。

我在初始化管道中定义了路由,如下所示:

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" });
     }
}
Run Code Online (Sandbox Code Playgroud)

路由已正确添加到路由表中,并且在调试时就已存在。现在,当我尝试调用方法“ test”时,找不到路由,并且调试器未在操作中达到断点。

我正在尝试不同的路线:

  • /localhost/mysite/home/forms/test
  • /localhost/forms/test (默认网站)

但到目前为止没有运气。

----更新-

更深入地讲,我注意到Sitecore的行为有问题。如果上下文项为空(简化),则TransferRoutedRequest处理器应该中止httpRequestBegin管道,将控制权交还给MVC。经过一些检查后,它会发生,其中一项是对RoutTable数据的检查。但是对RouteTable.Routes.GetRouteDatareturn 的调用始终为null,这使处理器可以在不中断管道的情况下返回。我改写了它以使其正确地中止管道,但是即使我调用method 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();
   }
}
Run Code Online (Sandbox Code Playgroud)

这就是我改写它的方式:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 6

这是一个来自我的项目的工作示例。

自定义路线注册:

namespace Test.Project.Pipelines.Initialize
{
    public class InitRoutes : Sitecore.Mvc.Pipelines.Loader.InitializeRoutes
    {
        public override void Process(PipelineArgs args)
        {
            RegisterRoutes(RouteTable.Routes);
        }

        protected virtual void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute(
                "Test", // Route name
                "api/test/{controller}/{action}/{id}", // URL with parameters
                 new { id = UrlParameter.Optional }
                );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

初始化管道配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
     <pipelines>
         <initialize>
            <processor type="Test.Project.Pipelines.Initialize.InitRoutes, Test.Project"
         patch:after="processor[@type='Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, Sitecore.Mvc']" />
        </initialize>
     </pipelines>
  </sitecore>
</configuration>
Run Code Online (Sandbox Code Playgroud)