C#访问Office365 SharePoint下载文件遇asmx站点不存在错误
问题描述
使用拥有完全访问权限的凭据从Office 365 SharePoint下载文件时,出现以下错误:
Microsoft.SharePoint.Client.ClientRequestException: 'Cannot contact site at the specified URL https://xxxx.sharepoint.com/sites/my_files/all%20Files. There is no Web named "/sites/my_files/all Files/_vti_bin/sites.asmx"'
相关代码如下:
static void Main(string[] args) { string url = "https://xxxxx.sharepoint.com/sites/my_files/all%20Files"; string folderpath = "https://xxxxxxx.sharepoint.com/sites/my_files/all%20Files/Task"; string templocation = @"c:\Downloads\Sharepoint\"; Program.DownloadFilesFromSharePoint(url, folderpath, templocation); } static void DownloadFilesFromSharePoint(string siteUrl, string siteFolderPath, string localTempLocation) { string userName = "aaaa@xxxxxx.com"; string pswd = "ssssss@1043"; SecureString password = new SecureString(); foreach (var c in pswd.ToCharArray()) password.AppendChar(c); var ctx = new ClientContext(siteUrl); //ctx.Credentials = new NetworkCredential(userName, password, "smtp-mail.outlook.com"); ctx.Credentials = new SharePointOnlineCredentials(userName, password); FileCollection files = ctx.Web.GetFolderByServerRelativeUrl(siteFolderPath).Files; ctx.Load(files); if (ctx.HasPendingRequest) { ctx.ExecuteQuery(); //getting error here : Cannot contact site at the specified URL. There is no Web named "*.asmx" } foreach (File file in files) { FileInformation fileInfo = File.OpenBinaryDirect(ctx, file.ServerRelativeUrl); ctx.ExecuteQuery(); var filePath = localTempLocation + "\\" + file.Name; System.IO.FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite); fileInfo.Stream.CopyTo(fileStream); } }
问题分析
- ClientContext初始化错误:
ClientContext需要绑定到SharePoint站点的根URL(如https://xxxxx.sharepoint.com/sites/my_files),而非具体文件夹URL。原代码传入文件夹路径,导致程序在错误位置查找站点服务文件(_vti_bin/sites.asmx),触发"No Web named"错误。 - 文件夹路径格式错误:
GetFolderByServerRelativeUrl要求传入服务器相对路径(从站点根开始的路径,如/sites/my_files/all Files/Task),而非完整绝对URL,原代码参数不符合API要求。 - 资源未正确释放:原代码中
FileStream未手动释放,存在资源泄漏风险。
实现方案(修正后的代码)
using System; using System.IO; using System.Security; using Microsoft.SharePoint.Client; class Program { static void Main(string[] args) { // 站点根URL,而非文件夹URL string siteUrl = "https://xxxxx.sharepoint.com/sites/my_files"; // 服务器相对路径,从站点根起始 string folderRelativePath = "/sites/my_files/all Files/Task"; string localTempLocation = @"c:\Downloads\Sharepoint\"; // 确保本地下载目录存在 Directory.CreateDirectory(localTempLocation); DownloadFilesFromSharePoint(siteUrl, folderRelativePath, localTempLocation); } static void DownloadFilesFromSharePoint(string siteUrl, string folderServerRelativePath, string localTempLocation) { string userName = "aaaa@xxxxxx.com"; string pswd = "ssssss@1043"; // 安全创建只读SecureString SecureString password = new SecureString(); foreach (char c in pswd) { password.AppendChar(c); } password.MakeReadOnly(); // 使用站点根URL初始化ClientContext,并用using自动释放资源 using (var ctx = new ClientContext(siteUrl)) { ctx.Credentials = new SharePointOnlineCredentials(userName, password); // 通过服务器相对路径获取目标文件夹 Folder targetFolder = ctx.Web.GetFolderByServerRelativeUrl(folderServerRelativePath); FileCollection files = targetFolder.Files; ctx.Load(files); ctx.ExecuteQuery(); foreach (File file in files) { // 用using自动释放文件流资源 using (FileInformation fileInfo = File.OpenBinaryDirect(ctx, file.ServerRelativeUrl)) using (FileStream fileStream = new FileStream(Path.Combine(localTempLocation, file.Name), FileMode.OpenOrCreate, FileAccess.Write)) { fileInfo.Stream.CopyTo(fileStream); } Console.WriteLine($"已下载文件: {file.Name}"); } } } }
关键修改说明
- 将
ClientContext初始化URL改为站点根URL,确保程序正确指向SharePoint站点。 - 将文件夹路径改为服务器相对路径,符合
GetFolderByServerRelativeUrl的参数要求。 - 使用
using语句包裹ClientContext、FileInformation和FileStream,自动释放资源,避免泄漏。 - 添加
Directory.CreateDirectory(localTempLocation)确保本地下载目录存在,防止写入失败。 - 优化
SecureString创建逻辑并设置为只读,提升安全性。
内容的提问来源于stack exchange,提问作者Kumar
相关产品推荐
相关产品推荐

