Sitecore MVC 自定义路由,同时仍然使用 Sitecore 渲染管道

Sitecore MVC Custom route while still using the Sitecore rendering pipeline

我正在使用 Sitecore 7.5 和 Sitecore 8(2 个具有相同需求的独立项目)。我们将内容项存储在存储桶中,但它们本身不是页面项(它们没有绑定表示,它们只是数据项,可能来自不同的来源,包括项目存储桶)。

所以这是问题的总体布局: 我们想要呈现项目的页面会是这样的 /sitecore/content/home/news 我们需要能够解析项目名称后的路径信息作为控制器渲染的数据负载。

所以,到目前为止,我尝试过的方法包括按照以下方式创建自定义路线:

            routes.MapRoute(
            "Blog", 
            "blog/{*pathInfo}", 
            new
            {
                scItemPath = "/sitecore/content/Home/Blog",
                controller = "Blog",
                action = "DefaultAction"
            });

我从 RenderCustomRoutes 管道加载路由,并将其配置为在不同的测试尝试中从 Sitecore InitializeRoutes 管道之前和之后调用。

我从 http://www.sitecore.net/learn/blogs/technical-blogs/john-west-sitecore-blog/posts/2012/10/using-sitecore-keys-in-mvc-routes-with-the-sitecore-aspnet-cms.aspx 和一些相关文章中引用了这个。

按照他修改说明或继续解决其他问题的其他文章并不能解决我的情况。问题是,none 这个作品。在这种情况下,控制器被正确调用,但是当我在渲染上下文中获取项目本身时,我没有获得页面渲染的任何其余部分。有没有办法从这里启动渲染管道,或者使用博客项目的其余演示详细信息到 assemble 页面并手动执行?

我尝试过的另一条路线只是试图将路径信息作为数据传递给现有博客页面 url,但我最终得到了 404。

我不知道我是在徒劳无功,还有更好的方法,还是我只是在某处遗漏了一块。在 Webforms 中,我可能已经完成 url 重写以在不使用查询字符串的情况下实现这一点,但我希望路由被设计为像这样处理事情,我看到的文章似乎让我认为它是可能。

我一直在考虑的其他事项: John West 说 Sitecore 有 4 种方法来处理 MVC 请求

1.忽略请求:允许 ASP.NET MVC 处理它,就好像没有安装 Sitecore,而不建立 Sitecore 上下文。

2.应用路由:使用MVC路由指定的控制器和动作。

3.应用指定的操作:使用上下文项中指定的控制器和操作。

4.应用视图:使用Sitecore的默认控制器和操作来调用上下文项中上下文设备的布局详细信息中定义的视图。

我使用自定义路由得到的结果似乎适合#2,但我需要的更像是#3#4 同时仍使用自定义路线。

所以,我发现我不完全满意的一个答案是:

我创建了布局的副本,呈现视图并使用 @Html.Sitecore().Rendering("<id>", <datasource>) 手动呈现页面的其余部分。它会工作,但它并不像我希望看到的那样优雅,所以我仍然愿意寻求更好的解决方案。

由于您存储桶中的项目没有任何 Presentation,我相信用路线处理这个问题会很棘手。这可能是可能的,希望其他人会插话但是...

您可以使用 wildcard Items 来实现您的目标。这将取决于组件的确切设置和结构,但只需创建一个名为 * 的项作为 /sitecore/content/Home/Blog 的子项。然后您可以在此通配符项上设置演示详细信息等。

现在任何 url 都将匹配此项。您需要在某个时候解析 Item,它可能在 Controller 本身中,您将需要解析 URL 然后查找要在渲染中使用的项目。 注意 Context.Item 仍然是通配符 * 项,因此您必须在代码中创建一个新变量然后填充您的模型:

Item requestedItem = Sitecore.Context.Database.GetItem("resolved-path");
Model.Name = requestedItem.Name;
Model.MyProperty = requestedItem["My Property"];

但是,在 ItemResolver 管道之后解析项目,然后将 guid 存储在 Sitecore.Context.Items 字典中可能会更好:

Item requestedItem = Sitecore.Context.Database.GetItem("resolved-path");
Sitecore.Context.Items["wildcard-guid"] = requestedItem.ID.ToString();

这样您就可以在多个组件中使用它并将其设置为组件的数据源(来自代码),例如面包屑、主要内容等。从缓存的角度来看,这也可能是有益的,因为您可以使用 VaryByData 选项启用缓存。如果找不到项目,您也可以抛出适当的 404,如果需要,可以设置 Sitecore.Context.Item = null

您还需要能够处理 link 生成,因此您需要 create a custom LinkProvider 生成一些友好的 URL。

希望这是有道理的!我必须尽快做类似的事情,这是迄今为止我想出的最佳选择...