使用SharePoint EventHandler added与updated 事件遇到的错误与解决方法
之前遇到这样的功能需求:增加/更新 库中的数据时,同时要更新本身一些column,发现偶尔报错的情况,经过不断查找资料与调试,啃代码,终于找问题与解决方法,现在分享出来。
Added问题: 例如:添加一个wiki page之后,将其URL访问地址,加到当前Item数据的指定column中,(为了可读取URL,做成<a>的href,点击访问)
做法:库加EventHandler,监听added事件,获取url,之后将url保存在指定column中。
偶尔出现错误信息: the document is modified by the SharePoint\System user. 更新信息失败
Updated问题: 在调试之后发现listItem.Update()和listItem.SystemUpdate()都会递归调用updated事件,形成死循环。
对这两种情况的解释与解决方法:
Added问题分析解决:
SharePoint 默认情况,如adding 事件以同步方式执行,added事件以异步方式执行;还有修改数据时,使用了数据库事件,加lock,提高数据一致性。所以added默认是使用异步方式,而碰到之前的数据的lock没放开,added报错。所以改为同步方式,等待lock释放之后,再执行,就可以解决。
feature XML 修改如下:
<Receiver>
<Name>NoticeEventReceiverItemAdded</Name>
<Type>ItemAdded</Type>
<Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
<Class>TianjinProject.NoticeEventReceiver.NoticeEventReceiver</Class>
<SequenceNumber>10000</SequenceNumber>
<Synchronization>Synchronous</Synchronization>
</Receiver>
Updated问题分析解决:
循环自调用,注意13与16行代码
1 public override void ItemUpdated(SPItemEventProperties properties) 2 { 3 try 4 { 5 using (SPWeb web = properties.OpenWeb()) 6 { 7 web.AllowUnsafeUpdates = true; 8 SPList list = properties.List; 9 SPListItem listItem = properties.ListItem; 10 string url = list.Fields.GetField("网页地址").InternalName; 11 listItem[url]= "http://aa.com"; 12 //截断事件监听,解决循环自调用, 13 this.EventFiringEnabled = false; 14 listItem.SystemUpdate(); 15 //更新完后加回事件 16 this.EventFiringEnabled = true; 17 web.AllowUnsafeUpdates = true; 18 } 19 } 20 }