由于没有客户端对象模型所具有的请求/文件大小限制,我决定使用 SaveBinaryDirect 方法将文档上传到共享点站点。

该应用程序执行两件事,添加一个文件夹(使用客户端对象模型),然后将选定的文件上传到刚刚创建的文件夹中(使用 Save Binary Direct)。

这对我这里的设置来说效果很好。但在我们的客户站点,文件夹创建良好,但文件上传部分返回“未经授权 401”错误。

            SP.ClientContext ctx = new SP.ClientContext(siteurl);
            SP.Web currentWeb = ctx.Web;
            //Pass user details from config (That has owner permissions)
            ctx.Credentials = new NetworkCredential(username, password, domain);   
            //create folder method (checks if the folder exists and creates using Client Object Model)
            CreateFolder(ctx,libraryUrl,folderName)

            //Save Binary Direct Method
            string fileUrl = "/"+ libraryname + "/" + folderName + "/" + fileName;
            using (data)
            {
                //upload by passing the context, file url, file data stream, 
                //set overwrite to true
                SP.File.SaveBinaryDirect(ctx, fileUrl,data, true);
            }

这让我想到两件事之一

  1. 共享点或 Web 服务器上需要更改有关授权/身份验证的设置。
  2. 我应用网络凭据的方式不正确。因为它仅适用于客户端对象模型,而不适用于直接保存二进制文件。

我知道我们能够使用客户端对象模型,如果不是配置/设置问题,我们可能需要进行另一个版本。

对此有更多经验的人对为什么要这样做有一些想法吗?

有帮助吗?

解决方案

如果您使用的是SharePoint 2013,则无法使用SaveBinaryDirect,它不适用于索赔身份验证。saveBinaryDirect制作的呼叫不包括所需的授权cookie。在此博客文章的评论中讨论了详细信息:如何在Office 365和SharePoint在线进行活动身份验证

更新(2016年7月2日):

在看到詹姆斯爱的评论后,我拍了另一个看法。我不确定改变了,但我的测试表明saveBinaryDirect现在正在使用SharePoint 2013和SharePoint Online。

这是我使用的代码:

// var context = new ClientContext("http://intranet.wingtip.com/sites/demo/");
// context.Credentials = System.Net.CredentialCache.DefaultCredentials;

var context = new ClientContext("https://robwindsor2.sharepoint.com/sites/demo/");
context.Credentials = new SharePointOnlineCredentials(loginName, securePassword);

var web = context.Web;
var lib = web.Lists.GetByTitle("Documents");

context.Load(lib);
context.Load(lib.RootFolder);
context.ExecuteQuery();

var fileName = "Test.docx";
var filePath = @"C:\Users\robwindsor\Desktop\" + fileName;
using (var fs = new FileStream(filePath, FileMode.Open))
{
    Microsoft.SharePoint.Client.File.SaveBinaryDirect(context, lib.RootFolder.ServerRelativeUrl + "/" + fileName, fs, true);
}

var query = new CamlQuery();
query.ViewXml = "<View></View>";
var files = lib.GetItems(query);

context.Load(files, c => c.Include(f => f.File));
context.ExecuteQuery();

foreach(ListItem item in files)
{
    Console.WriteLine(item.File.Name);
}

Console.WriteLine("Done");        
.

其他提示

试试:

FileCreationInformation fci = new FileCreationInformation();

fci.Content = newFile.Bytes;

fci.Url = sourceFile.Url;

fci.Overwrite = true;

Microsoft.SharePoint.Client.File replacedFile = list.RootFolder.Files.Add(fci);

context.Load(replacedFile);

context.ExecuteQuery();
.

我能够使用客户端对象模型从文件系统上传文件到SharePoint 2010。

如果您正在获得未经授权的401,请确保提供正确的凭据和目标SharePoint文档库文件夹的正确相对URL。

ClientContext ctx = new ClientContext(Siteurl);
ctx.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
var sourceFilePath = @"C:\test\test.xlsx";
var targetUrl = "/Shared%20Documents";
var targetFileUrl = String.Format("{0}/{1}", targetUrl, Path.GetFileName(sourceFilePath));
var fs = new FileStream(sourceFilePath, FileMode.Open);
Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, targetFileUrl, fs, true);
var uploadedFile = ctx.Web.GetFileByServerRelativeUrl(targetFileUrl);
var listItem = uploadedFile.ListItemAllFields;
listItem.Update();
ctx.ExecuteQuery();
.

我认为你必须添加这个:

ctx.RequestTimeout = 3600000;
.

我遇到了同样的问题,发现了一个解决方法,尽管我不知道它是否是合法的。

 System.Net.WebClient webClient = new System.Net.WebClient();

 System.Uri uri = new Uri(url); //Create a uri object with the file name but without extension

 webClient.Credentials = new NetworkCredential(username,password,domain);        //Network credentials to connect with the sharepoint server

 webClient.UploadFile(uri, "PUT", pFilePath);     //Upload File will push the file to the server
.

总而言之:你需要使用 服务器 相对 URL,即使上下文包含站点信息。

我也遇到了同样的问题,并使用 Fiddler 解决了它。当我使用客户端对象模型时,我使用站点路径创建了上下文,即”https://服务器/站点/站点名称“, 然后

var docs = web.Lists.GetByTitle(documentLibraryName);
SP.File uploadFile = docs.RootFolder.Files.Add(newFile);
context.Load(uploadFile);
context.ExecuteQuery();

这导致了一个 POST 到 https://<server>/sites/<siteName>/_vti_bin/client.svc/ProcessQuery路径和文件名(和内容)由 CSOM 嵌入到 XML 中。

现在 SP.File.SaveBinaryDirect 签名是 SaveBinaryDirect(ClientContext context, string serverRelativeUrl, Stream stream, bool overwriteIfExists) ——但是请求 SaveBinaryDirect(context, "/<library>/<folder>/filename", stream, true) 失败并出现 401 错误。查看 Fiddler,这是提出的请求:

PUT https://<server>/<library>/<filename>

尽管上下文 包括 该网站,你必须给它 整个路径 从服务器根目录。成功的调用是

SaveBinaryDirect(context, "/sites/<sitename>/<library>/<folder>/filename", stream, true)

这会导致 PUT 到正确的位置。参数 被称为 serverRelativeUrl 毕竟。

许可以下: CC-BY-SA归因
scroll top