1

I'd like to download a file from Sharepoint online using a non-interactive C# program. Recently MFA was enabled, and since then I'm unable to get the files with any user through my code, though I can still access it through the portal web access.

At first I have tried using the following, getting an The sign-in name or password does not match one in the Microsoft account system. when executing the query (using either username@mydomain.com or username@mydomain.onmicrosoft.com)

var ctx = new ClientContext(Properties.Settings.Default.SharepointBaseUrl)
{
    Credentials = credentials,
};

var web = ctx.Web;

ctx.Load(web);
try
{
    ctx.ExecuteQuery();
}
catch (Exception ex)
{
    return string.Empty;
}

var fileUrl = $"{web.ServerRelativeUrl}/{file.Location}";
var fi = Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx, fileUrl);

Then I generated an AppId and AppSecret, and used the following code:

var authenticationManager = new OfficeDevPnP.Core.AuthenticationManager();
var ctx = authenticationManager.GetAppOnlyAuthenticatedContext(
                                            "https://mydomain.sharepoint.com/sites/defaultcollection/MyDir",
                                            appId,
                                            appSecret);

But got a 401 unauthorized when trying to access the file with SharePoint.Client.File.OpenBinaryDirect(ctx, fileUrl);

Alenros
  • 816
  • 7
  • 23

1 Answers1

3

Use File.OpenBinaryStream() instead like this:

    using Microsoft.SharePoint.Client;
    using OfficeDevPnP.Core;
    using System.IO;
    
    
    string siteUrl = "https://tenant.sharepoint.com/";
    using (var ctx = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, "yourappid", "yourappsecret"))
    {
        ctx.Load(ctx.Web, p => p.Title);
        ctx.ExecuteQuery();
        Console.WriteLine(ctx.Web.Title);
        Microsoft.SharePoint.Client.File file = ctx.Web.GetFileByUrl("https://tenant.sharepoint.com/Shared%20Documents/test.txt");
        ctx.Load(file);
        ctx.ExecuteQuery();
        string filepath = @"C:\temp\" + file.Name;
        Microsoft.SharePoint.Client.ClientResult<Stream> mstream = file.OpenBinaryStream();
        ctx.ExecuteQuery();

        using (var fileStream = new System.IO.FileStream(filepath, System.IO.FileMode.Create))
        {
            mstream.Value.CopyTo(fileStream);
        }

    };
Jerry
  • 3,480
  • 1
  • 10
  • 12
  • It worked! Would you care to explain the difference in your answer? – Alenros Feb 25 '21 at 07:34
  • 1
    This is because of File.OpenBinaryDirect can't be used when authenticate with OAuth App-Only credential, please check the same question here for detailed infofrmation: https://stackoverflow.com/questions/45674435/401-unauthorized-exception-while-downloading-file-from-sharepoint – Jerry Feb 25 '21 at 07:47