Tuesday, January 16, 2024

Add file from API, in Sharepoint doc library

public async Task<IResult> UploadFile(HttpRequest request)

{

    CSOMHelper helper = null;

    ClientContext clientContext = null;

    string _libraryName = string.Empty;

    string fileName = string.Empty;

    bool result = false;

    string SPItemId = string.Empty;

    try

    {

        helper = new CSOMHelper();

        clientContext = await helper.GetAppOnlyContext(_config.GetValue<string>("SharePointSiteUrl"), _config.GetValue<string>("clientId"), _config.GetValue<string>("clientSecret"));

        byte[] binaryData;

        var context = request; //_httpContext.HttpContext.Request;

        string returnString = String.Empty;

        string opportunityNumber = string.Empty;//Request.Form.Files[0].FileName.Split('#')[1];

        string attachmentConfigId = string.Empty;//Request.Form.Files[0].FileName.Split('#')[2];


        if (context.Headers.ContainsKey("foldername"))

        {

            _libraryName = context.Headers["foldername"];

        }


        if (context.Form.Files.Count > 0)

        {

            Stream stream = context.Form.Files[0].OpenReadStream();

            BinaryReader br = new BinaryReader(stream);

            binaryData = br.ReadBytes((int)context.Form.Files[0].Length);

            //string timeStamp = helper.GetTimestamp(DateTime.Now);

            string timeStamp = DateTime.Now.ToShortDateString();

            Guid uploadId = Guid.NewGuid();

            fileName = uploadId + "_" + context.Form.Files[0].FileName;

            FileEntity fileEntity = new FileEntity()

            {

                FileName = fileName,

                FileStream = binaryData

            };


            string year = DateTime.Now.ToString("yyyy");


            List<string> lstOfFolders = new List<string>();

            lstOfFolders.Add(year);

            Folder folder = await helper.AddNestedFolders(clientContext, _libraryName, lstOfFolders, true);


            ListItem lisItemToAdd = await helper.UploadFileBySlices(clientContext, fileEntity, _libraryName, null, 100, folder);


            SPItemId = Convert.ToString(lisItemToAdd["ID"]);


            return await Task.FromResult(Results.Ok(new { id = SPItemId, filename = fileName }));

        }

    }

    catch (Exception ex)

    {

        _logger.LogEventError(new LogMessage { Message = ex.Message, StackTrace = ex.StackTrace });

        return await Task.FromResult(Results.BadRequest(ex.Message));

    }

    finally

    {

        helper.DisposeContext(clientContext);

    }

    return await Task.FromResult(Results.Ok(new { id = SPItemId, filename = fileName }));

}

 



public async Task<Folder> AddNestedFolders(ClientContext clientContext, string strLibrary, List<string> lstFolders, bool isExecute = true)

{

    try

    {

        List oList = clientContext.Web.Lists.GetByTitle(strLibrary);

        var folder = oList.RootFolder;

        clientContext.Load(folder);

        clientContext.ExecuteQuery();

        foreach (string item in lstFolders)

        {

            folder = folder.Folders.Add(item);

        }

        clientContext.Load(folder);


        if (isExecute)

            clientContext.ExecuteQueryAsync().Wait();

        return folder;

    }

    catch (Exception ex)

    {

        throw ex;

    }

}


/// <summary>

/// Upload large files to a library by slices of 2mb by default

/// </summary>

/// <param name="clientContext"></param>

/// <param name="fileEntity"></param>

/// <param name="libraryName"></param>

/// <param name="filePropertiesToUpdate"></param>

/// <param name="FirstTimeUploadSize"></param>

/// <param name="foldertoUpload"></param>

/// <returns></returns>

public async Task<ListItem> UploadFileBySlices(ClientContext clientContext, FileEntity fileEntity, string libraryName, List<ListDataEntitiy> filePropertiesToUpdate, int FirstTimeUploadSize = 2, Folder foldertoUpload = null)

{

    ListItem oFileItem = null;

    try

    {


        var dataStream = fileEntity.FileStream;

        var fileName = fileEntity.FileName;

        var oWeb = clientContext.Web;


        clientContext.RequestTimeout = Timeout.Infinite;


        // Each sliced upload requires a unique ID.

        Guid uploadId = Guid.NewGuid();


        var dateTime = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff");

        // Get the name of the file.

        string uniqueFileName = fileName;// oFileInputInMemory.DemoNumber + "_" + oFileInputInMemory.RunID + "_" + oFileInputInMemory.Chamber + "_"+ strUserId+"_"+ dateTime+"_" + fileName;// Path.GetFileName(fileName);

        List docLibrary = clientContext.Web.Lists.GetByTitle(libraryName);

        if (foldertoUpload == null)

            foldertoUpload = docLibrary.RootFolder;


        // File object.

        Microsoft.SharePoint.Client.File uploadFile = null;


        // Calculate block size in bytes.

        decimal blockSizeFirst = FirstTimeUploadSize * 1024 * 1024;

        int blockSize = FirstTimeUploadSize * 1024 * 1024;



        // Get the size of the file.

        long fileSize = dataStream.Length;//new FileInfo(fileName).Length;

        if (fileSize <= blockSize)

        {

            int tempblockSize = Convert.ToInt32(fileSize / 2);

            blockSize = tempblockSize + 1;

        }



        if (fileSize <= blockSizeFirst)

        {

            using (Stream stream = new MemoryStream(dataStream))

            {

                FileCreationInformation fileInfo = new FileCreationInformation();

                fileInfo.ContentStream = stream;

                fileInfo.Url = uniqueFileName;

                fileInfo.Overwrite = true;

                uploadFile = foldertoUpload.Files.Add(fileInfo);

                clientContext.Load(uploadFile);

                oFileItem = uploadFile.ListItemAllFields;

                clientContext.Load(oFileItem);

                clientContext.ExecuteQuery();

                //if (filePropertiesToUpdate != null)

                //{

                //    this.AssignValuesToListItem(filePropertiesToUpdate, oWeb, oFileItem);

                //    oFileItem = await this.SaveListItem(clientContext, oFileItem, true);

                //}

            }

        }

        else

        {

            // Use large file upload approach.

            ClientResult<long> bytesUploaded = null;


            //FileStream fs = null;

            Stream stream = new MemoryStream(dataStream);

            try

            {

                using (BinaryReader br = new BinaryReader(stream))

                {

                    byte[] buffer = new byte[blockSize];

                    Byte[] lastBuffer = null;

                    long fileoffset = 0;

                    long totalBytesRead = 0;

                    int bytesRead;

                    bool first = true;

                    bool last = false;


                    // Read data from file system in blocks.

                    while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)

                    {

                        totalBytesRead = totalBytesRead + bytesRead;


                        // You've reached the end of the file.

                        if (totalBytesRead == fileSize)

                        {

                            last = true;

                            //   first = false;

                            // Copy to a new buffer that has the correct size.

                            lastBuffer = new byte[bytesRead];

                            Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);

                        }


                        if (first)

                        {

                            using (MemoryStream contentStream = new MemoryStream())

                            {

                                // Add an empty file.

                                FileCreationInformation fileInfo = new FileCreationInformation();

                                fileInfo.ContentStream = contentStream;

                                fileInfo.Url = uniqueFileName;

                                fileInfo.Overwrite = true;

                                uploadFile = docLibrary.RootFolder.Files.Add(fileInfo);

                                // Start upload by uploading the first slice.

                                using (MemoryStream s = new MemoryStream(buffer))

                                {

                                    // Call the start upload method on the first slice.

                                    bytesUploaded = uploadFile.StartUpload(uploadId, s);



                                    oFileItem = uploadFile.ListItemAllFields;

                                    clientContext.Load(oFileItem);

                                    if (filePropertiesToUpdate != null)

                                    {

                                        this.AssignValuesToListItem(filePropertiesToUpdate, oWeb, oFileItem);

                                        oFileItem = await this.SaveListItem(clientContext, oFileItem, true);

                                    }


                                    // fileoffset is the pointer where the next slice will be added.

                                    fileoffset = bytesUploaded.Value;

                                }


                                // You can only start the upload once.

                                first = false;

                            }

                        }

                        else

                        {

                            if (last)

                            {

                                // Is this the last slice of data?

                                using (MemoryStream s = new MemoryStream(lastBuffer))

                                {

                                    // End sliced upload by calling FinishUpload.

                                    uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);

                                    clientContext.ExecuteQuery();

                                }

                            }

                            else

                            {

                                //  clsLogger.Log("SensorsController", "UploadFile", "middle: " + buffer.Length.ToString());


                                using (MemoryStream s = new MemoryStream(buffer))

                                {

                                    // Continue sliced upload.

                                    bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);

                                    clientContext.ExecuteQuery();

                                    // Update fileoffset for the next slice.

                                    fileoffset = bytesUploaded.Value;

                                }

                            }

                        }

                    } // while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0)

                }

            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally

            {

                if (stream != null)

                {

                    stream.Dispose();

                }

            }

        }

    }

    catch (Exception ex)

    {

        throw ex;

    }

    return oFileItem;

}