当文档列表项被远程事件接收器更改时,我需要处理它。远程事件接收器连接到 itemupdated 事件中。这有一个明显的问题,如果我更新 itemupdated 事件中的项目,我将陷入虚幻循环。
为了避免这种无限循环,并且在没有像 EventFireringEnabled 这样的东西的情况下,我会在老式 SharePoint 开发中使用,我想在列表项上添加一个"已处理"标志以指示文档已处理。
然后,逻辑流如下所示。
- 文档已添加到库中 - 这里没有什么特别之处
- 元数据在列表项上填写 - 项目更新事件触发
- 远程事件接收器焕发出勃勃生机。检查"已处理"标志。如果为真,则什么都不做,如果为假,则继续。使用文档上的元数据,它"处理"它。文档已更新,列表项"已处理"标志设置为 true。
我遇到的麻烦是在单个事务中更新文档和列表项。
我的保存文件方法如下所示:
private void SaveFile(List list, string url, MemoryStream memoryStream)
{
var newFile = new FileCreationInformation
{
ContentStream = memoryStream,
Url = url,
Overwrite = true
};
File updatedFile = list.RootFolder.Files.Add(newFile);
ListItem item = updatedFile.ListItemAllFields;
item["Processed"] = true;
item.Update();
_clientContext.ExecuteQuery();
}
但这表现为两个更新。文件更新,然后列表项更新。有谁知道我是否可以将其强制到单个更新中?
实际上,在指定的示例中,只有一个请求提交到服务器(当调用ClientContext.ExecuteQuery
方法时)。可以使用Fiddler等网络监控工具进行验证。
这是原始示例的略微修改版本,带有注释:
private static void SaveFile(List list, string url, Stream contentStream,IDictionary<string,object> itemProperties)
{
var ctx = list.Context;
var fileInfo = new FileCreationInformation
{
ContentStream = contentStream,
Url = url,
Overwrite = true
};
var file = list.RootFolder.Files.Add(fileInfo); //1. prepare to add file
var item = file.ListItemAllFields;
foreach (var p in itemProperties)
item[p.Key] = p.Value;
item.Update(); //2. prepare list item to update
ctx.ExecuteQuery(); //3. submit request to the server that includes adding the file and updading the associated list item properties.
}
更新
使用具有以下签名的 ListItem.ValidateUpdateListItem 方法:
public IList<ListItemFormUpdateValue> ValidateUpdateListItem(
IList<ListItemFormUpdateValue> formValues,
bool bNewDocumentUpdate,
string checkInComment
)
此方法类似于
UpdateOverwriteVersion
方法 在服务器 API 上可用。验证更新列表项设置计量数据 如果 bNewDocumentUpdate 参数设置为 true,则将调用 更新覆盖版本方法,该方法将更新而不递增 版本
private static void SaveFile(List list, string url, Stream contentStream,List<ListItemFormUpdateValue> itemProperties)
{
var ctx = list.Context;
var fileInfo = new FileCreationInformation
{
ContentStream = contentStream,
Url = url,
Overwrite = true
};
var file = list.RootFolder.Files.Add(fileInfo);
var item = file.ListItemAllFields;
item.ValidateUpdateListItem(itemProperties, true, string.Empty);
ctx.ExecuteQuery();
}
用法:
var list = ctx.Web.Lists.GetByTitle(listTitle);
using (var stream = System.IO.File.OpenRead(filePath))
{
var itemProperties = new List<ListItemFormUpdateValue>();
itemProperties.Add(new ListItemFormUpdateValue() { FieldName = "Processed", FieldValue = "true" });
SaveFile(list, pageUrl, stream,itemProperties);
}