我在ItemResolver之后插入了一个自定义管道处理器,其中我使用内容编辑器从下拉链接中选择的新项目覆盖当前上下文项。
如果我通过我的网站和我的处理器通过正常请求转到该动态项目并且我更改了我的上下文项目,那么它将呈现相同的项目:
public override void Process(HttpRequestArgs args)
{
// some code
Context.Item = dropLink.TargetItem;
}
奇怪的是,如果我通过商品API发出请求,则sitecore会成功更改商品
//api call
Context.Item = Context.Database.SelectSingleItem("fast:/sitecore/content/mysite/dynamicitem");
这是我的配置文件:
<pipelines>
<httpRequestBegin>
<processor patch:after="* @type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" type="MyDll.Web.Pipelines.LandingPageResolver,MyDll.Web" />
</httpRequestBegin>
</pipelines>
答案 0 :(得分:4)
由于您正在使用MVC,因此使用一组不同的管道(再次)解析该项目,因此您需要在那里进行修补。
GetFromRouteUrl
管道中的mvc.getPageItem
处理器将args.Result
设置为与请求的网址匹配的项目,然后最终设置为Context.Item
,因此它基本上会重置项目到基于URL的“正确”项目,并覆盖您之前所做的更改。
您需要向mvc.getPageItem
添加一个需要处理器,并使用一些逻辑来检查上下文项是否已经解析。
在ItemResolver中更新你的代码并存储一个布尔值,表明你已经使用自定义逻辑解析了,这节省了两次运行解析逻辑:
public override void Process(HttpRequestArgs args)
{
// some code
Context.Item = dropLink.TargetItem;
Context.Items["custom::ItemResolved"] = true;
}
创建一个新类,检查您的自定义逻辑是否已解析该项:
public class CheckItemResolved: GetPageItemProcessor
{
public override void Process(GetPageItemArgs args)
{
if (args.Result == null)
{
var resolved = Sitecore.Context.Items["custom::ItemResolved"];
if (MainUtil.GetBool(resolved, false))
{
// item has previously been resolved
args.Result = Sitecore.Context.Item;
}
}
return;
}
}
然后将其修补:
<pipelines>
<mvc.getPageItem>
<processor type="MyProject.Custom.Pipelines.CheckItemResolved, MyProject.Custom"
patch:before="*[@type='Sitecore.Mvc.Pipelines.Response.GetPageItem.GetFromRouteUrl, Sitecore.Mvc']" />
</mvc.getPageItem>
</pipelines>
紧接着的管道是GetFromFromUrl()
,通常会通过重新解析项目来设置args.Result
。通过将其设置回Context.Item,处理器将提前突破并保留以前的逻辑。