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

时间:2015-03-09 10:16:06

标签: sharepoint csom sharepoint-online

我需要在远程事件接收器更改文档列表项时处理它。远程事件接收器连接到itemupdated事件。这有一个明显的问题,如果我在itemupdated事件中更新项目,我将陷入无限循环。

为了避免这种无限循环,并且在没有类似EventFiringEnabled的情况下,我将使用旧学校SharePoint开发,我想在列表项上添加“已处理”标志以指示文档已被处理。

逻辑流程看起来像这样。

  • 文档已添加到库中 - 这里没什么特别的
  • 元数据填写在列表项上 - ItemUpdated事件触发
  • 远程事件接收器栩栩如生。检查“已处理”标志。如果是真的,什么也不做,如果是假的,继续。使用文档上的元数据,它“处理”它。文档已更新,列表项“已处理”标志设置为true。

我遇到的麻烦是在单个事务中更新文档和列表项。

我的SaveFile方法如下所示:

    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();
    }

但这表现为两次更新。文件已更新,然后列表项为。有谁知道我是否可以强制进行单次更新?

1 个答案:

答案 0 :(得分:3)

实际上,在指定的示例中,只有单个请求被提交给服务器(当调用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 method

public IList<ListItemFormUpdateValue> ValidateUpdateListItem(
    IList<ListItemFormUpdateValue> formValues,
    bool bNewDocumentUpdate,
    string checkInComment
)
  

此方法类似于UpdateOverwriteVersion方法   可在服务器API上使用。 ValidateUpdateListItem设置metdata   如果bNewDocumentUpdate参数设置为true将调用   UpdateOverwriteVersion方法将更新而不会递增   版本

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);    
}