作为我们应用程序的要求,我们使用以下方法在文档库中添加具有其他文件属性的文件:
private static SPFile AddFile(SPListItem item, Stream stream, string filename, SPFolder destinationFolder, string comment)
{
string destinationFilePath = destinationFolder.Url + "/" + filename;
using (var web = item.Web)
{
object file;
switch (SPFarm.Local.BuildVersion.Major)
{
case 12:
var parameters2007 = new object[] { destinationFilePath, stream, false, item.File.Author, web.CurrentUser, item.File.TimeCreated, item.File.TimeLastModified, null, comment, true };
file = destinationFolder.Files.GetType().GetMethod("AddInternal", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(Stream), typeof(Boolean), typeof(SPUser), typeof(SPUser), typeof(DateTime), typeof(DateTime), typeof(Hashtable), typeof(string), typeof(Boolean) }, null).Invoke(destinationFolder.Files, parameters2007);
break;
default:
case 14:
var parameters2010 = new object[] { destinationFilePath, stream, null, item.File.Author, web.CurrentUser, item.File.TimeCreated, item.File.TimeLastModified, comment, true };
file = destinationFolder.Files.GetType().GetMethod("Add", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(Stream), typeof(Hashtable), typeof(SPUser), typeof(SPUser), typeof(DateTime), typeof(DateTime), typeof(string), typeof(Boolean) }, null).Invoke(destinationFolder.Files, parameters2010);
break;
}
return file as SPFile;
}
}
我们使用反射的原因是,我们需要在创建文件时覆盖文件的created_by和modified_by属性;事实证明,用其他方法来做这件事是非常痛苦的。Sharepoint 2007 的 API 仅限于实现这一点,因此需要反思。
有一种情况web.CurrentUser是共享点/系统(通常是因为上下文处于提升状态),只要它用于modified_by就可以了。但是,在 Sharepoint 2013 中,SPFileCollection.Add方法不会覆盖created_by属性,它只是将其保留为CurrentUser(独立于 modified_by 参数),无论我们如何处理它。结果弄乱了我们应用程序的整个工作流程。
我使用反射器检查了 Sharepoint 2013 的 dll 文件,似乎方法及其参数与 2010 相同。
创建文件后更新属性是我想避免的,因为我对它有不好的记忆。通常解决一个问题会产生多个问题,我不记得详细的问题。更不用说这种变化需要在 3 个不同的版本中进行广泛的测试。
是否有一种功能性方法可以使用 SPFileCollection.Add 在 Sharepoint 2013 上覆盖文件的created_by属性?