通过ClientContext更新Sharepoint文档库列的“创建者”

时间:2015-10-02 08:19:29

标签: c# sharepoint-2013

我想通过客户端上下文更新SharePoint中的“创建者”列,但我的代码无效。该列是文档库列。

我尝试了几个选项。我的第一个代码块无法更新字段,但我的第二个代码块确实可以解决这个问题,但它无法管理我的第一个代码块能够执行的大于150 MB的文件。

这是我的第一个代码块:

using (var ctx = new ClientContext(spSiteUrl))
{
    ctx.RequestTimeout = 1000000;
    Web web = ctx.Web;

    string strUser = "spDomain\\adminUser1";

    var file = ctx.Web.GetFileByServerRelativeUrl(newServerRelPath);
    var item = file.ListItemAllFields;

    //First approach and it doesn't work
    // -> Start
    FieldUserValue fuvUser = new FieldUserValue();
    User oUser = web.EnsureUser(strUser);
    ctx.Load(oUser,
    props=>props.Id,
    props=>props.LoginName);
    item["Author"] = oUser;
    item["Created_x0020_By"] = oUser;
    // -> End

    //Second approach and still it doesn't work
    // -> Start
    List list = web.GetList(spDocLibUrl);
    list.Fields.GetByInternalNameOrTitle("Author").ReadOnlyField = false;
    list.Fields.GetByInternalNameOrTitle("Created_x0020_By").ReadOnlyField = false;
    list.Update();
    item["Author"]=web.EnsureUser(strUser);
    item["Created_x0020_By"] = web.EnsureUser(strUser);
    // -> End

    item.Update();
    ctx.ExecuteQuery();

}

如何更新“创建者”字段

我在代码上做的另一种方法实际上可以更新Created By字段,但我的问题是我无法上传大于150 MB的文件。

这是我的第二个代码块:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite site = new SPSite(spSiteUrl))
    {
        using (SPWeb web = site.OpenWeb())
        {
            //read file in filestream
            System.IO.FileStream fStream = System.IO.File.OpenRead(filePath);
            byte[] contents = new byte[fStream.Length];
            fStream.Read(contents, 0, (int)fStream.Length);
            fStream.Close();

            web.AllowUnsafeUpdates = true;
            SPFolder rootFolder = web.GetFolder(spFolderUrl);

            string strUser = "spDomain\\adminUser1";
            SPUser userCreatedBy = web.EnsureUser(strUser);

            //This part sets the created by field successfully but fails to add files bigger than 150mb.
            SPFile file = rootFolder.Files.Add(item.Name, contents,userCreatedBy,userCreatedBy,DateTime.Now,DateTime.Now);

            int id = file.Item.ID;
            SPListItem listItem = file.Item;//docsLibrary.GetItemById(id);
            listItem["Created"] = item.CreationTime;
            listItem["Modified"] = item.LastWriteTime;
            listItem.Update();

            web.AllowUnsafeUpdates = false;
        }
    }
});

很明显,我的第二个代码块没有RequestTimeOut设置。也许这可能是它无法上传更大文件的原因。我想设置RequestTimeOut,但是 如何在我的代码中添加它?还是有其他更好的方法来执行此操作

业务要求:以编程方式将大于150 MB(300 MB,800 MB甚至1 GB)的文件上载到SharePoint文档库,并将创建者字段设置为谁是本地源文件夹中文件的作者。

如果我的问题有任何不明确之处,请告诉我,以便我可以更新。

1 个答案:

答案 0 :(得分:1)

尝试设置MaxReceivedMessageSize:

SPWebService ws = SPWebService.ContentService;
SPClientRequestServiceSettings clientSettings = ws.ClientRequestServiceSettings;
clientSettings.MaxReceivedMessageSize = 10485760;
ws.Update();
Console.WriteLine(clientSettings.MaxReceivedMessageSize);

或使用HTTP DAV:

ClientContext context = new ClientContext("http://spdevinwin");
using (FileStream fs = new FileStream(@"C:\Work\Files\17580_FAST2010_S03_Arch.pptx", FileMode.Open))
{
Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, "/documents/17580_FAST2010_S03_Arch from client OM.pptx", fs, true);
}

更改使用修改:

RunCodeWithNewClientContext((ctx, item) => {
    const string template = "i:0#.f|membership|{0}@<tenant>.onmicrosoft.com";
    var modifiedBy = ctx.Web.EnsureUser(string.Format(template, vm.ModifiedBy));
    var createdBy = ctx.Web.EnsureUser(string.Format(template, vm.CreatedBy));

    ctx.Load(modifiedBy);
    ctx.Load(createdBy);
    ctx.ExecuteQuery();

    item["Editor"] = modifiedBy.Id;
    var modifiedByField = new ListItemFormUpdateValue {
        FieldName = "Modified_x0020_By",
        FieldValue = modifiedBy.Id.ToString()
    };

    item["Author"] = createdBy.Id;
    var createdByField = new ListItemFormUpdateValue {
        FieldName = "Created_x0020_By",
        FieldValue = createdBy.Id.ToString()
    };

    item["Modified"] = vm.ModifiedAt.ToUniversalTime();
    item["Created"] = vm.CreatedAt.ToUniversalTime();

    // it doesn't matter if you add both modifiedByField and createdByField.
    // As long as the list is non-empty all changes appear to carry over.
    var updatedValues = new List<ListItemFormUpdateValue> { modifiedByField, createdByField };
    item.ValidateUpdateListItem(updatedValues, true, "Ignored on explicit checkin/checkout");
    ctx.ExecuteQuery();
});