作为我们应用程序的一项要求,我们使用以下方法在文档库中添加具有其他文件属性的文件:
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 是 sharepoint / system (通常是因为上下文处于提升状态),只要它用于 modified_by 即可。但是,在Sharepoint 2013中, SPFileCollection.Add 方法不会覆盖 created_by 属性,它只是将其保留为 CurrentUser (独立于modified_by参数)我们这样做。这会导致我们的应用程序整个工作流程变得混乱。
我使用反射器检查了Sharepoint 2013的dll文件,似乎该方法及其参数与2010年相同。
创建文件后更新属性是我想避免的,因为我对它有不好的回忆。通常修复一个问题创建了几个,我不记得详细的问题。更不用说这种改变需要在3个不同版本中进行大量测试。
是否有一种功能方法可以在Sharepoint 2013上使用SPFileCollection.Add覆盖文件的 created_by 属性?