在我的Sitecore 6.1.0安装中,我通过以下方式(在Web.config中)实现自己的自定义处理程序,钩住了"item:add"事件:
<event name="item:added">
<handler type="Sitecore.Data.Fields.ItemEventHandler, Sitecore.Kernel" method="OnItemAdded" />
<handler type="my.project.Classes.OnSaveItemHandler, my.project" method="OnItemAdded" />
</event>
这样做的目的是为项目强制使用唯一的名称——换句话说,在我的OnItemAdded方法中,我想对与要添加的项目同名的任何其他项目进行Lucene搜索。
每次在Sitecore结构中添加项时,都会调用OnItemAdded方法。但我的问题是,每个项目都会多次调用该方法。我看到每个添加的项目调用它6到26次,这取决于我在Sitecore结构中添加项目的位置。我的OnItemAdded方法的主体为空:
protected void OnItemAdded(object obj, EventArgs args)
{
}
添加项时第一次调用该方法时,args
参数中的项是正确的项。如果项目名称为theItemName
,则FullPath属性将如下所示:
/sitecore/content/theItemName
除了第一次外,每次项目看起来都是正确的,但项目的路径看起来是这样的:
[orphan]/sitecore/content/theItemName
为什么要将[孤立]位添加到完整路径上?为什么OnItemAdded方法被调用不止一次,尽管我只添加了一个项?
我相信像这样的事件存在已知的问题,其中方法将被调用多次。我知道我也有过类似的经历,当项目创建时,我试图用程序为该项目创建一个角色。约翰·韦斯特说,作为预防措施:
我似乎记得Sitecore有时会多次触发一些事件,所以你可能想检查一下这个〔…〕
然后,John提供了一个链接到一篇名为"使用Sitecore 拦截项目更新"的博客文章
在我的代码中,我进行了一次检查,检查我要查找的操作是否已经发生,例如项目的角色是否存在。在您的情况下,在方法中检查可能会有点困难。也许你可以做一些偷偷摸摸的事情,比如:
protected void OnItemAdded(object obj, EventArgs args) {
Item item = // code to extract item from args, I forgot it
if(item.Paths.FullPath.StartsWith("/sitecore/content")) {
// do your stuff because you know its the first time the event fired
}
}
再说一遍,这是非常粗鲁的。如果Sitecore支持无法提供任何更好的选项(或者Stack overflow上没有任何更好的选择),我想说这是最后的手段。
在这种情况下,我会考虑创建一个命令模板(从Sitecore自己的创建项派生而来),并在那里添加强制唯一名称功能。
额外的好处是,如果名称不是唯一的,那么项目一开始就不会被创建。
参考编号:http://sdn.sitecore.net/upload/sitecore6/datadefinitioncookbook-a4.pdf#search=%22command%22
我也遇到过同样的问题,看起来这个问题与代理项有关。
我会添加一个项目,然后获得许多[孤立]路径,创建的每个项目都有不同的id。
关闭代理项将停止创建[孤立]项。
编辑-发现阴影表已损坏,截断了master数据库中的Shadows表,并截断了core中的Links数据库,然后重建链接数据库。我得到了46条这样的孤立记录,这些记录中的项目本不应该在上面设置代理项目。