首页 > 解决方案 > 以编程方式从 MS 团队下载文件

问题描述

以前,我开发了一个应用程序,它从公司的 Sharepoint 站点下载一个文件,然后用它执行一些魔术。

自从迁移到 MS Teams 之后,我正在尝试更新应用程序以使用新平台。但是,我在下载文件时遇到了各种各样的问题。

我的旧(为 Sharepoint 工作)代码使用 aWebClient根据用户先前提供的凭据检索文件:

    private string GetSchedule(string username, string password, string domain)
    {

        string tempPath = Path.GetTempFileName().Replace(".tmp", ".xlsm");
        using (WebClient client = new WebClient())
        {
            client.Credentials = new NetworkCredential(username, password, domain);
            try
            {
                client.DownloadFile(_networkSchedulePath, tempPath);
            }
            catch (WebException e)
            {
                if (e.Message.Contains("401"))
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>("Invalid Credentials Provided"));
                    Finished?.Invoke(this, null);
                    return null;
                }
                if (e.Message.Contains("404"))
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>("File Not Found"));
                    Finished?.Invoke(this, null);
                    return null;
                }
                else
                {
                    StatusUpdated?.Invoke(this, new EventArgs<string>(e.Message));
                    Finished?.Invoke(this, null);
                    return null;
                }
            }
        }
        return tempPath;
    }

但是,当我将它与新团队链接一起使用时,我遇到了403 Forbidden错误。那么有没有办法以编程方式从 MS Teams 检索文件?

标签: c#sharepointmicrosoft-teams

解决方案


我在评论中弄错了。简单地替换NetworkCredentialsSharePointOnlineCredentials不是解决方案。

我不确定以下是否是“正确”的方法,但它有效并且看起来非常可靠。请试一试:

private static string GetFile(string path, string username, string password, string domain)
{
    var secureString = new SecureString();
    foreach (var ch in password)
    {
        secureString.AppendChar(ch);
    }

    string tempPath = Path.GetTempFileName().Replace(".tmp", ".xlsm");
    using (WebClient client = new WebClient())
    {
        var credentials = new SharePointOnlineCredentials(username, secureString);

        client.Headers[HttpRequestHeader.Cookie] = credentials.GetAuthenticationCookie(new Uri(path));
        try
        {
            client.DownloadFile(path, tempPath);
        }
        catch (WebException e)
        {
            // Error Handling
        }
    }
    return tempPath;
}

另一种选择是使用 CSOM 而不是直接使用 web 客户端。注意,我在使用 Microsoft.SharePoint.Client NuGet 包时遇到了错误,OpenBinaryDirect()看起来这个包已经过时了。现在使用的似乎是 Microsoft.SharePointOnline.CSOM 或 Microsoft.SharePoint2019.CSOM:

private static string GetFileWithClientContext(string path, string username, string password, string domain)
{
    var secureString = new SecureString();
    foreach (var ch in password)
    {
        secureString.AppendChar(ch);
    }
    string tempPath = Path.GetTempFileName().Replace(".tmp", Path.GetExtension(path));
    using (var context = new ClientContext(path))
    {
        context.Credentials = new SharePointOnlineCredentials(username, secureString);

        try
        {
            using (var file = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, new Uri(path).AbsolutePath))
            using (var outFile = System.IO.File.OpenWrite(tempPath))
            {
                file.Stream.CopyTo(outFile);
            }
        }
        catch (WebException e)
        {
            // Error Handling
        }
    }
    return tempPath;
}

推荐阅读