在Sitecore中创建REST服务

在Sitecore中创建REST服务,rest,sitecore,sitecore6,Rest,Sitecore,Sitecore6,我正在尝试在Sitecore根目录中构建REST服务。我的应用程序开始如下所示: void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = System.Web.Http.RouteParameter

我正在尝试在Sitecore根目录中构建REST服务。我的应用程序开始如下所示:

void Application_Start(object sender, EventArgs e) 
{
    RouteTable.Routes.MapHttpRoute(
        name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = System.Web.Http.RouteParameter.Optional });
}
我的URL如下所示:

void Application_Start(object sender, EventArgs e) 
{
    RouteTable.Routes.MapHttpRoute(
        name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = System.Web.Http.RouteParameter.Optional });
}
http://{mydomain}/api/books

我有正确的控制器和所有这些

但Sitecore一直将我重定向到404页面。我已经在web.config中添加了IgnoreUrlPrefixes节点的路径,但没有效果。如果让我猜的话,我会认为Sitecore的处理程序在我的代码有机会执行之前就已经重定向了,但我真的不知道


有人知道哪里可能出错吗?

你的评估是正确的。在
httpRequestBegin
管道中需要一个处理器来中止Sitecore的处理。请参阅此答案中的
systemwebroutingsolver

本文还对其进行了描述:

但我也会在这里包含代码。:)

然后在
httpRequestBegin
配置中:

<processor type="My.SystemWebRoutingResolver, My.Classes" />

另一个我使用效果很好的选项是使用内容树、“星形”项和专用于此目的的子布局/布局组合:

[siteroot]/API/*/*/*/*/*/*/*/*/*
上面的路径允许您拥有1到9个段-如果您需要更多,您可能需要重新考虑您的流程,IMO。这还保留了所有Sitecore上下文。Sitecore在文件夹中找不到项目时,会尝试查找“全明星捕获”项目,如果该项目存在,则会呈现该项目,而不是返回404

有几种方法可以执行restful方法和子布局(如果您想按深度将它们分离以简化解析,可以使用子布局)

您可以选择遵循通用的“标准”,并使用GET、PUT和POST调用与这些项进行交互,但如果没有自定义后端缓存代码,则无法使用Sitecore缓存)。或者,您可以将API拆分为三个不同的树:

[siteroot]/API/GET/*/*/*/*/*/*/*/*/*
[siteroot]/API/PUT/*/*/*/*/*/*/*/*/*
[siteroot]/API/POST/*/*/*/*/*/*/*/*/*
这允许缓存GET请求(因为GET请求应该只检索数据,而不是更新数据)。请确保使用正确的缓存方案,如果您打算在任何这些上下文中使用该方案,则基本上应该基于数据、用户等的每个排列进行缓存

如果要创建多个子布局,我建议创建一个基类来处理GET、PUT和POST的常规方法,然后将这些类用作子布局的基类

在子布局中,您只需获取请求对象,获取路径(如果使用查询,则获取查询),将其拆分,然后像使用标准路由一样执行切换案例逻辑。对于PUT,使用Response.ReadBinary()。对于POST,使用Request.Form对象获取所有表单元素,并对它们进行迭代以处理提供的信息(将所有表单数据放在一个JSON对象中,封装为字符串可能是最简单的方法(因此.NET将其视为字符串,因此只有一个属性)然后,根据用户指定的post路径,post中只有一个元素需要反序列化

复杂?是的。有效?是的。推荐?嗯…如果你在共享环境中(多个站点)如果您不希望管道处理器中的每个站点都进行此处理,那么此解决方案就可以工作。如果您可以通过Sitecore使用MVC,或者在更改管道处理器时没有问题,那么这可能会更有效


基于内容的方法的一个好处是上下文生命周期与标准Sitecore页面(登录等)完全相同,因此您拥有与生命周期中任何其他项目相同的控件。消极的一面是,您必须在整个页面生命周期加载到代码之前处理它…管道处理器可以跳过Sitecore的许多过程,直接获取您需要的数据,使其更快。

要使用管道初始值设定项进行路由,请执行以下操作: 它将像:

公共类初始值设定项

{
        public void Process(PipelineArgs args)
        {
        RouteCollection route = RouteTable.Routes;
        route.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}",
        new { id = RouteParameter.Optional });
        }
}
在配置文件中,您将拥有:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <initialize>
    <processor type="_YourNameSpace.Initializer,_YourAssembly" />
      </initialize>
     </pipelines>
  </sitecore>       
</configuration>


快乐编码

您可能想看看


它与您正在构建的几乎相同。

您是否也可以将
/api
添加到
IgnoreUrlPrefixes
设置中?@Alexander:我尝试过,但它根本没有改变行为。您是否确定这应该有效?通过使用管道,您可以保留对Sitecore.Context中许多值的访问权限,例如数据库、站点、语言。