Sharepoint CSOM Deleting Folder and contents - c#

Although this works, it seems rather verbose. Is there a more terse way? Using CSOM and a C# .Net Framework application. Really just want to delete the folder and contents. Thanks.
public static void DeleteFileAndFolder(string file)
{
using (var context = Sharepoint.ClientContext)
{
context.Credentials = new NetworkCredential(
Sharepoint.ExtranetUserName,
Sharepoint.ExtrantPassword);
var web = context.Web;
var list = web.Lists.GetByTitle(Sharepoint.ListTitle);
var deleteFile = list.RootFolder.FindFiles(file).Single();
deleteFile.Context.Load(deleteFile.ListItemAllFields);
deleteFile.Context.ExecuteQuery();
var folderUrl = deleteFile.ListItemAllFields["FileDirRef"].ToString();
var folder = deleteFile.ListItemAllFields.ParentList.ParentWeb.GetFolderByServerRelativeUrl(folderUrl);
deleteFile.Context.Load(folder);
deleteFile.Context.ExecuteQuery();
deleteFile.DeleteObject();
folder.DeleteObject();
context.ExecuteQuery();
}
}

You don`t need to get list, you can get folder from web object, see sample to delete files in folder:
ClientContext ctx = GetCtx();
Folder rootFolder = ctx.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl("your path here"));
ctx.Load(rootFolder, f => f.Files);
ctx.ExecuteQuery();
foreach (var file in rootFolder.Files)
{
file.DeleteObject();
}
ctx.ExecuteQuery();

Related

How to save files (pdf/excel) in another server?

I have a web API hosted on server 101.111.111.111. It accepts files in form data. My question is how to save this files in another server(Ex: 101.111.111.112)?. I didn't find much examples for this in web.
I have this code to save in my local folder:
var file = Request.Form.Files[i];
var folderName = Path.Combine("D:\\Loans", fileInfo.LoanID, fileInfo.Alias );
var pathToSave = Path.Combine(Directory.GetCurrentDirectory(), folderName);
if (!Directory.Exists(pathToSave))
{
Directory.CreateDirectory(pathToSave);
}
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fullPath = Path.Combine(pathToSave, fileName);
var dbPath = Path.Combine(folderName, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
file.CopyTo(stream);
}
One way is that create a share folder on server 101.111.111.112 and then map that shared folder with map network drive...(In Windows) on server 101.111.111.111 and then use that folder like local folder in your code.

GitLab API - How to list all files in subfolder

I'm having quite the time trying to get this seemingly simplistic line of code to work using C#. Trying to get a list of all my files in my repo.
File structure below:
MyRepo
-directory_01
--myFile_01.jpg
--myFile_02.jpg
This line of code lists all my directories and works great:
var streamTask = client.GetStringAsync(https://myURL/api/v4/projects/myRepo/repository/tree?private_token=myToken"
According to the api, to get my files only I should use files/:file_path attribute or archive.<file extension> to get my files.
//Get all .jpg files
var streamTask = client.GetStringAsync(https://myURL/api/v4/projects/myRepo/repository/archive.jpg?private_token=myToken"
OR
//Get one file
var streamTask = client.GetStringAsync(https://myURL/api/v4/projects/myRepo/repository/files/directory_01%2FmyFile_01%2Ejpg?private_token=myToken"
//result: 404
When you this API you also need to pass the branch name
Change
var streamTask = client.GetStringAsync(https://myURL/api/v4/projects/myRepo/repository/files/directory_01%2FmyFile_01%2Ejpg?private_token=myToken"
To
var streamTask = client.GetStringAsync(https://myURL/api/v4/projects/myRepo/repository/files/directory_01%2FmyFile_01%2Ejpg?private_token=myToken&ref=<branch_name>"
Just in case anyone else runs into this issue, here's a way to do this:
// Get list of files***********
string treeUri = $"{project}tree?private_token={projectToken}&ref=master";
string treeData = await client.GetStringAsync(treeUri);
List<AssetEntry> json = System.Text.Json.JsonSerializer.Deserialize<List<AssetEntry>>(treeData);
Console.WriteLine("FILE LIST:\n");
foreach (var item in json)
{
Console.WriteLine(item.name + " " );
}

SharePoint 2016 FileNotFound Exception

Through C#, I'm trying to download a file from SharePoint (SharePoint 2016). Below is the code I'm using:
site = new ClientContext(url);
//credential setting has no issues. So I am skipping it. I am using NetworkCredentials
site.Load(web);
site.ExecuteQuery();
List list = web.Lists.GetByTitle("Documents");
site.Load(list);
site.ExecuteQuery();
site.Load(list.RootFolder);
site.ExecuteQuery();
site.Load(list.RootFolder.Folders);
site.ExecuteQuery();
Folder folder = web.GetFolderByServerRelativeUrl(sharePointPath);
site.Load(folder);
site.ExecuteQuery();
site.Load(folder.Files);
site.ExecuteQuery();
While the last "site.ExecuteQuery()" is being executed, an exception is thrown:
ExceptionMessage: File not found
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream
But, there are files in that path and manually we are able to upload and download with the same credentials. URLs, Paths, etc have been double-checked and no issues with that.
When I print "folder.ItemCount", it is printing the correct no. of files in the folder. Only in ExecuteQuery for loading files, it is throwing exception.
Build settings: .NET framework 4.5 and x64
In other posts, people advised to change to .NET 3.5 but it was for SharePoint 2010. Further, changing it to 3.5 ends up in lot of build errors for me.
Please help in fixing this.
Here is the code snippet to download a file from SharePoint default Document library and save into a local folder:
static void Main(string[] args)
{
string siteUrl = "http://sp2016/sites/dev";
ClientContext clientContext = new ClientContext(siteUrl);
var list = clientContext.Web.Lists.GetByTitle("Documents");
var listItem = list.GetItemById(5);
clientContext.Load(list);
clientContext.Load(listItem, i => i.File);
clientContext.ExecuteQuery();
var fileRef = listItem.File.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);
var fileName = Path.Combine(#"C:\Test", (string)listItem.File.Name);
using (var fileStream = System.IO.File.Create(fileName))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
I was working with collection and above solution did not work for me, here is how I did so that it can help someone.
List list = web.Lists.GetByTitle("Events");
ListItemCollection listItems = list.GetItems(cmlqry);
context.Load(listItems);
context.ExecuteQuery();
if (listItems != null)
{
foreach (var listItem in listItems)
{
Console.WriteLine("Id: {0}, Title: {1}", listItem["ID"].ToString(), listItem["Title"].ToString());
context.Load(listItem.AttachmentFiles);
context.ExecuteQuery();
foreach (var file in listItem.AttachmentFiles)
{
Console.WriteLine("File: {0}", file.FileName);
var fileRef = file.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, fileRef);
var fileName = Path.Combine(#"C:\temp\Events\", String.Format("{0}_{1}", listItem.Id, file.FileName));
using (var fileStream = System.IO.File.Create(fileName))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
}
}

SharePoint Online, uploading files larger than 2mb using SharePointClient

While trying to upload files to SharePoint online, remotely via SharePointClient upload, I am encountering a file size limit of 2mb. From my searches it seems that people have overcome this limit using PowerShell, but is there a way to overcome this limit using the native SharePointClient package in .Net C#? Here is my existing code sample:
using (var ctx = new Microsoft.SharePoint.Client.ClientContext(httpUrl))
{
ctx.Credentials = new Microsoft.SharePoint.Client.SharePointOnlineCredentials(username, passWord);
try
{
string uploadFilename = string.Format(#"{0}.{1}", string.IsNullOrWhiteSpace(filename) ? submissionId : filename, formatExtension);
logger.Info(string.Format("SharePoint uploading: {0}", uploadFilename));
new SharePointClient().Upload(ctx, sharePointDirectoryPath, uploadFilename, formatData);
}
}
I have read from the following site that you can use the ContentStream just not sure how that maps to SharePointClient (if at all):
https://msdn.microsoft.com/en-us/pnp_articles/upload-large-files-sample-app-for-sharepoint
UPDATE:
Per the suggested solution I now have:
public void UploadDocumentContentStream(ClientContext ctx, string libraryName, string filePath)
{
Web web = ctx.Web;
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
FileCreationInformation flciNewFile = new FileCreationInformation();
// This is the key difference for the first case - using ContentStream property
flciNewFile.ContentStream = fs;
flciNewFile.Url = System.IO.Path.GetFileName(filePath);
flciNewFile.Overwrite = true;
List docs = web.Lists.GetByTitle(libraryName);
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
}
Still not quite working, but will update again when it is successful. Current error is :
Could not find file 'F:approot12-09-2017.zip'.
FINALLY
I am using files from Amazon S3 so the solution was to take my byte data and to stream that to the call:
public void UploadDocumentContentStream(ClientContext ctx, string libraryName, string filename, byte[] data)
{
Web web = ctx.Web;
FileCreationInformation flciNewFile = new FileCreationInformation();
flciNewFile.ContentStream = new MemoryStream(data); ;
flciNewFile.Url = filename;
flciNewFile.Overwrite = true;
List docs = web.Lists.GetByTitle(libraryName);
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
You can use FileCreationInformation to create a new file and provide the contents via a FileStream. You can then add the file to the destination library. This should help you get around 2mb limit you are encountering with upload method you are using. Example below:
FileCreationInformation newFile = new FileCreationInformation
{
Url = fileName,
Overwrite = false,
ContentStream = new FileStream(fileSourcePath, FileMode.Open)
};
var createdFile = list.RootFolder.Files.Add(newFile);
ctx.Load(createdFile);
ctx.ExecuteQuery();
In the example the destination library is list you will need to get reference to this first. I can show you how to do this if required.

Returning Guid of newly created item in Sharepoint Library

I am using the method
File.SaveBinaryDirect
in Microsoft.SharePoint.Client to insert new documents in a Sharepoint Library. just wondering what is the most effective way of getting the Guids of those new records.
Well, you've just saved the file to a particular URL - get the File by that URL, and then use the ListItemAllFields property to get the ListItem that would contain those IDs
From here:
var FileSrvRelUrl = "/sub/doclib/Folder/File.doc";
using (var fileStream = new MemoryStream(new byte[100]))
{
Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, FileSrvRelUrl, fileStream, false);
}
var web = clientContext.Web;
var f = web.GetFileByServerRelativeUrl(FileSrvRelUrl);
var item = f.ListItemAllFields;
item["SomeField"] = "Value";
item.Update();
clientContext.Load(item, i=>i.Id);
clientContext.ExecuteQuery();

Categories

Resources