0

I want to open a filestream from a sharepoint file (Microsoft.SharePoint.Client.File) but I don't seem to find out how.

I only have access to Microsoft.SharePoint.Client because the Microsoft.SharePoint package can't be installed due to some errors.

This is the code I have so far:

ClientContext ctx = new ClientContext("https://factionxyz0.sharepoint.com/sites/faktion-devs");
ctx.Credentials = CredentialCache.DefaultCredentials;
Microsoft.SharePoint.Client.File temp = ctx.Web.GetFileByServerRelativeUrl(filePath);
FileStream fs = new FileStream(???);
Mout Pessemier
  • 653
  • 1
  • 7
  • 23

3 Answers3

1

You can only create a System.IO.FileStream if the file exists on a physical disk (or is mapped to a disk via the Operating System).

Workaround: Are you able to access the raw URL of the file? In which case, download the file to disk (if the size is appropriate) and then read from there.

For example:

var httpClient = new HttpClient();

// HTTP GET Request
var response = await httpClient.GetAsync(... SharePoint URL ...);

// Get the Content Stream
var stream = await response.Content.ReadAsSteamAsync();


// Create a temporary file
var tempFile = Path.GetTempFileName();

using (var fs = File.OpenWrite(tempFile))
{
   await stream.CopyToAsync(fs);
}

// tempFile now contains your file locally, you can access it like
var fileStream = File.OpenRead(tempFile);

// Make sure you delete the temporary file after using it
File.Delete(tempFile);
James Woodall
  • 531
  • 4
  • 9
1

FileStream must map to a file. The following code demonstrates how to get a stream via CSOM, then we can convert it to FileStream by using a temp file.

ResourcePath filepath = ResourcePath.FromDecodedUrl(filename);

Microsoft.SharePoint.Client.File temp = context.Web.GetFileByServerRelativePath(filepath);

ClientResult<System.IO.Stream> crstream = temp.OpenBinaryStream();

context.Load(temp);
context.ExecuteQuery();

var tempFile = Path.GetTempFileName();
FileStream fs = System.IO.File.OpenWrite(tempFile);

if (crstream.Value != null){
      crstream.Value.CopyTo(fs);
}

As for Azure function temp storage, you may take a reference of following thread: Azure Functions Temp storage Or you can store data to Azure storage: Upload data to blob storage with Azure Functions

Best Regards, Baker Kong

Baker_Kong_MSFT
  • 1,328
  • 1
  • 2
  • 7
  • Weird thing is, I don't have access to the `OpenBinaryStream()` method on SharePoint files? – Mout Pessemier Apr 10 '20 at 08:23
  • Did you reference the packages correctly? This method is in Microsoft.SharePoint.Client.dll.(https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-csom/jj170439(v=office.15)) – Baker_Kong_MSFT Apr 10 '20 at 08:56
  • I don't find that packge provided by Microsoft, only the one provided by faisal and when I install that package, I still don't have access to that method – Mout Pessemier Apr 10 '20 at 09:27
  • I have found the package but I can't install it: `Package Microsoft.SharePoint.dll 15.0.4867.1000 is not compatible with netcoreapp2.1 (.NETCoreApp,Version=v2.1). Package Microsoft.SharePoint.dll 15.0.4867.1000 supports: microsoftsharepoint (Microsoft.SharePoint,Version=v0.0)` – Mout Pessemier Apr 10 '20 at 09:35
  • 1
    Microsoft.SharePoint.dll is server side code. ClientContext is in Microsoft.SharePoint.Client (CSOM). You can get it from nuget: https://www.nuget.org/packages/Microsoft.SharePointOnline.CSOM. And reference it in Function: https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#using-nuget-packages – Baker_Kong_MSFT Apr 13 '20 at 04:53
1

Been a while since the question was asked, however, this is how I solved this while I was working on a project. Obviously passing in the credentials directly like this isn't the best way, but due to timing constraints I was not able to convert this project into a newer version of .NET and use Azure AD.

Note that the class is implementing an interface.

public void SetServer(string domainName) {
    if (string.IsNullOrEmpty(domainName)) throw new Exception("Invalid domain name. Name cannot be null");
    _server = domainName.Trim('/').Trim('\\');
}

private string MapPath(string urlPath) {
    var url = string.Join("/", _server, urlPath);
    return url.Trim('/');
}

public ISharePointDocument GetDocument(string path, string fileName) {
    var serverPath = MapPath(path);
    var filePath = string.Join("/", serverPath, TemplateLibrary, fileName).Trim('/');
    var document = new SharePointDocument();
    var data = GetClientStream(path, fileName);

    using(var memoryStream = new MemoryStream()) {
        if (data == null) return document;
        data.CopyTo(memoryStream);
        var byteArray = memoryStream.ToArray();
        document = new SharePointDocument {
            FullPath = filePath,
            Bytes = byteArray
        };
    }

    return document;
}

public Stream GetClientStream(string path, string fileName) {
    var serverPath = MapPath(path);
    var filePath = string.Join("/", serverPath, TemplateLibrary, fileName).Trim('/');
    var context = GetClientContext(serverPath);

    var web = context.Web;

    context.Load(web);
    context.ExecuteQuery();

    var file = web.GetListItem(filePath).File;
    var data = file.OpenBinaryStream();

    context.Load(file);
    context.ExecuteQuery();

    return data.Value;
}

private static ClientContext GetClientContext(string serverPath) {
    var context = new ClientContext(serverPath) {
        Credentials = new SharePointOnlineCredentials("example@example.com", GetPassword())
    };

    return context;
}

private static SecureString GetPassword() {
    const string password = "XYZ";
    var securePassword = new SecureString();

    foreach(var c in password.ToCharArray()) securePassword.AppendChar(c);

    return securePassword;
}

Jacob
  • 177
  • 12