Logo
banner

Blogs

Download Large SharePoint Files From PowerApps Portal

, June 27, 2022 180 Views

A while ago, one of our clients gave us a vexing problem. They had a lot of rather large files, nearly 1 GB in size, stored in their SharePoint server. They wanted to allow their customers to be able to download these files from the company portal. The portal was the PowerApps Portal. But then, we found that when you use Portals to download large size files from the SharePoint, you may get timeout error.

The timeout error would suggest that the connection would drop after a specific amount of time. So, after much discussion over cups of tea we came up with a solution to this.

Realizing that using Web API than the portal we can work around almost all timeout errors, we decided to go with that.

Below is a Web API code that will read the file from the specified SharePoint location and download it in the specified location.

Controller:

public class DownloadFileFromSharepointController : ApiController 
  { 
    #region Public Methods 
    /// <summary> 
    /// Controller Method to get specific file from SharePoint folder and download on given path of local machine 
    /// </summary> 
    /// <param name="fileName">n\Name of the file that needs to be download</param> 
    /// <param name="pathToDownloadFile">Local machine path where the file will be downloaded</param> 
    /// <returns></returns> 
    [EnableThrottling] 
    public IHttpActionResult Get(string fileName,string pathToDownloadFile) 
    { 
      try 
      { 
        bool isSuccess = false; 
        StringBuilder errorLogMessage = new StringBuilder(string.Empty); 

        if (string.IsNullOrWhiteSpace(fileName) == false) 
        { 
          MemoryStream memoryStream = null; 
          memoryStream = APICommon.GetFileFromSharepointFolder(fileName); 
          if (memoryStream != null) 
          { 
            isSuccess = APICommon.DownloadFileInLocalMachine(fileName, pathToDownloadFile, memoryStream); 
          } 
        } 
        if (isSuccess) 
        { 
          return Ok(errorLogMessage.ToString()); } 
        else 
        { 
          return BadRequest(errorLogMessage.ToString()); } 
      } 
      catch (Exception ex) 
      { 
        return InternalServerError(ex); } 
    } 
    #endregion 
  }

Class file methods:

#region GetFileFromSharepointFolder 
    /// <summary> 
    /// Method to get file from the SharePoint folder 
    /// </summary> 
    /// <param name="fileName">Name of the file</param> 
    /// <returns>Object of memory stream</returns> 
    internal static MemoryStream GetFileFromSharepointFolder(string fileName) 
    { 
      string sharePointFileName = string.Empty; 
      string errorMsg = string.Empty; 
      MemoryStream memoryStream = new MemoryStream(); 

      try 
      { 
        string siteUrl = “Specify SharePoint URL” 
        string sharePointClientId = “Specify SharePoint UserName” 
        string sharePointClientSecret = “Specify SharePoint Password” 
        ClientContext clientContext = new ClientContext(siteUrl); 
        SecureString password = new SecureString(); 
        sharePointClientSecret.ToCharArray().ToList().ForEach(p => password.AppendChar(p)); 
        clientContext.Credentials = new SharePointOnlineCredentials(sharePointClientId, password); 
        List list = clientContext.Web.Lists.GetByTitle("Documents"); 
        Folder folder = clientContext.Web.GetFolderByServerRelativeUrl("Shared%20Documents/Specify folder name"); 

        clientContext.Load(folder); 

        clientContext.ExecuteQuery(); 

        CamlQuery camlQuery = new CamlQuery(); 
        camlQuery.ViewXml = @"<View Scope='Recursive'><Query></Query></View>"; 
        camlQuery.FolderServerRelativeUrl = "/sites/TestSitePOC/Shared%20Documents/ Specify folder name"; 

        ListItemCollection listItems = list.GetItems(camlQuery); 

        clientContext.Load(listItems); 
        clientContext.ExecuteQuery(); 

        for (int i = 0; i < listItems.Count; i++) 
        { 
          ListItem itemOfInterest = listItems[i]; 
          if (itemOfInterest != null) 
          { 
            sharePointFileName = Convert.ToString(itemOfInterest.FieldValues["FileLeafRef"]); 
            if (sharePointFileName.Equals(fileName, StringComparison.InvariantCultureIgnoreCase) == true) 
            { 
              clientContext.Load(list.RootFolder); 
              clientContext.ExecuteQuery(); 
              string relativeUrlForServerFile = $"{list.RootFolder.ServerRelativeUrl}/{folder.Name}/{fileName}"; 
              Microsoft.SharePoint.Client.File file = clientContext.Web.GetFileByServerRelativeUrl(relativeUrlForServerFile); 
              ClientResult<Stream> data = file.OpenBinaryStream(); 
              clientContext.Load(file); 
              clientContext.ExecuteQuery(); 

              if (data != null) 
              { 
                data.Value.CopyTo(memoryStream); 
                memoryStream.Position = 0; 
              } 

              break; 

            } 
          } 
        } 
      } 
      catch (Exception ex) 
      { 
        errorMsg = ex.Message; 
      } 
      return memoryStream; 
    } 
    #endregion 

#region DownloadFileInLocalMachine 
    /// <summary> 
    /// method to download file in given desination 
    /// </summary> 
    /// <param name="fileName">Name of the file</param> 
    /// <param name="filePath">Path to download the file </param> 
    /// <param name="memoryStream">Object of memory stream containing the data of the file</param> 
    /// <returns>Bool indicating method runs successfully</returns> 
    internal static bool DownloadFileInLocalMachine(string fileName, string filePath, MemoryStream memoryStream) 
    { 
      string errorMsg = string.Empty; 
      bool isSuccess = false; 
      try 
      { 
        string Destination = @filePath; 
        FileStream stream = new FileStream(Destination + "/" + fileName, FileMode.Create); 
        byte[] binary = ReadFully(memoryStream); 
        BinaryWriter writer = new BinaryWriter(stream); 
        writer.Write(binary); 
        writer.Close(); 
        isSuccess = true; 
      } 
      catch (Exception ex) 
      { 
        errorMsg = ex.Message; 
      } 
      return isSuccess; 
    } 
    #endregion

Hope this helps!

 


ATM Inspection PowerApp to ease ATM inspection and report generation process.
https://www.inkeysolutions.com/microsoft-power-platform/power-app/atm-inspection

Insert data into Many-to-Many relationship in Dynamics CRM very easily & quickly, using the Drag and drop listbox.
http://www.inkeysolutions.com/what-we-do/dynamicscrmaddons/drag-and-drop-listbox

Comply your Lead, Contact, and User entities of D365 CRM with GDPR compliance using the GDPR add-on.
https://www.inkeysolutions.com/microsoft-dynamics-365/dynamicscrmaddons/gdpr

Create a personal / system view in Dynamics CRM with all the fields on the form/s which you select for a particular entity using the View Creator.
http://www.inkeysolutions.com/what-we-do/dynamicscrmaddons/view-creator

mm

Inkey

INKEY is your solution partner.
Our focus is to deliver you in-time intelligent innovative solutions ("key") for the problems in hand. Maintaining a quality standard right from the inception of a project is our top most priority.

Our team of talented professionals will execute your projects with dedication and excellence. We take ownership and accountability for the effort that goes into meeting our client’s needs.

Years of experience and proven success of delivering innovative custom solutions.

More posts by

Leave a Reply

Your email address will not be published.

The maximum upload file size: 2 MB. You can upload: image, audio, video, document, spreadsheet, interactive, text, archive, code, other. Drop file here