SharePoint CSOM - 一起更新文档和列表项属性



当文档列表项被远程事件接收器更改时,我需要处理它。远程事件接收器连接到 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);    
}

最新更新