我有一个绑定到SharePoint 2010图片库的事件接收器。上传图片时,我想打开它进行处理。使用Web界面上载的文件工作正常,但通过Windows资源管理器视图复制的文件返回零字节。以下简化代码。
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
SPFile file = item.File;
byte[] buffer = file.OpenBinary(); //buffer has zero bytes for files copied in Windows Explorer!
}
如果我在打开前插入一个延迟,它就会起作用。
public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem item = properties.ListItem;
SPFile file = item.File;
System.Threading.Thread.Sleep(2000);
byte[] buffer = file.OpenBinary(); //buffer now populated correctly
}
但我认为ItemAdded仅在完成所有操作后调用,包括文件上传。 我还发现file.CanOpenFile(true)总是返回true,无论OpenBinary是否正常工作。
在调用OpenBinary()之前,如何确保文件已准备好打开? 我不喜欢Thread.Sleep解决方案,因为我确定更大的文件或更繁忙的服务器需要更多的等待。无法预测所需的时间,我不想循环并再试一次。
更新:我原本以为打开失败是由较大的文件引起的。问题已更新,以反映资源管理器视图的原因。我还发现Windows资源管理器副本也触发了ItemUpdated(两次),我可以在这里打开文件。有3个触发器有点乱,2个叫做1件事,所以我仍然愿意接受建议。
答案 0 :(得分:2)
我今天刚刚在SharePoint 2013上遇到过这个问题。我已经采纳了此处列出的建议并对其进行了改进。
让线程休眠2秒钟很好,但是当你有一个大文件时会发生什么?你将遇到同样的问题。
我的代码修复如下:
//Check if the SPContext is null since Explorer View isn't within the context
if (SPContext.Current == null)
{
//If the initial file length is 0, pause the thread for 2 seconds
if (properties.ListItem.File.Length == 0)
{
System.Threading.Thread.Sleep(2000);
//Since our item exists, run the GetItemById to instantiate a new and updated SPListItem object
var spFile = properties.List.GetItemById(properties.ListItemId);
//SharePoint places an Exclusive lock on the file while the data is being loaded into the file
while (spFile.File.LockType != SPFile.SPLockType.None)
{
System.Threading.Thread.Sleep(2000);
spFile = properties.List.GetItemById(properties.ListItemId);
//We need to check if the file exists, otherwise it will loop forever if someone decides to cancel the upload
if (!spFile.File.Exists)
return;
}
//If someone thought it was a good idea to actually load a 0 byte file, don't do anything else
if (spFile.File.Length == 0)
return;
}
}
答案 1 :(得分:0)
我在SP2010和SP2013中面临同样的问题。任何想法如何解决这个问题?
不知何故,这与更大的文件有关。小文件没有任何问题,较大的文件(400kb)将无法正常工作。
我只有一个提示。如果你复制&将文件通过Windows资源管理器(WebDAV)粘贴到库中,EventHandle(ItemAdded)将在创建文件后立即触发。但这并不意味着文件已经填满了数据。我曾经看过这个,我的调试器即使在窗口仍然忙于copyprocess的情况下也能达到我的断点。
很高兴知道copyprocess何时完成。我想我可以通过“spfile.openBinary()”做到这一点,如果它是空的,只需等待2秒再做一次,直到它会得到大于0字节的东西。但这不起作用!只有在第一次调用openBinary()之前等待它才有效,所有其他时间调用openBinary()都会产生相同的结果。