I have the following code:
ClientContext context = new ClientContext("https://Website.sharepoint.com/sites/Subsite");
context.Credentials = new SharePointOnlineCredentials(Username, GetPasswordFromConsoleInput(Password));
context.Load(context.Web);
List list = context.Web.Lists.GetByTitle("Documents");
context.ExecuteQuery();
CamlQuery query = new CamlQuery();
query.FolderServerRelativeUrl = "Documents/Folder1/Folder2/Folder3";
query.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
ListItemCollection folderItems = list.GetItems(query);
context.Load(folderItems);
context.ExecuteQuery();
foreach (ListItem li in folderItems)
{
Microsoft.SharePoint.Client.File file = li.File;
if (file != null)
{
//how to download all files
}
}
//How to download one single file in the root "Documents" folder with specific name
1) I need it to connect to a SharePoint365 website and download all the files in the specific folder in the subsite library. The files are located in the 3rd folder of the document library. The files should go to a network location \\server\d$\files
2) I need it to do the same thing but for only one single file in the root location of the document library with an specific name.
Now it gives me this error: 'The 'query.FolderServerRelativeUrl' argument is invalid.'
Thank you for any help!
Sample code for your reference.
string targetSiteURL = #"https://tenant.sharepoint.com/sites/lee";
var login = "user#tenant.onmicrosoft.com";
var password = "password";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(login, securePassword);
using (ClientContext clientContext = new ClientContext(targetSiteURL))
{
clientContext.Credentials = onlineCredentials;
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.Load(web, wb => wb.ServerRelativeUrl);
clientContext.ExecuteQuery();
List list = web.Lists.GetByTitle("mydoc3");
clientContext.Load(list);
Folder folder = web.GetFolderByServerRelativeUrl(web.ServerRelativeUrl + "/mydoc3/ParentFolder/");
clientContext.Load(folder);
clientContext.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
camlQuery.FolderServerRelativeUrl = folder.ServerRelativeUrl;
ListItemCollection listItems = list.GetItems(camlQuery);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
foreach(var item in listItems)
{
var file = item.File;
clientContext.Load(file);
clientContext.ExecuteQuery();
if (file != null)
{
Console.WriteLine(file.Name);
}
}
}
Console.ReadKey();
Related
I want to display files from a sharepoint folder that were modified by username. please help me for this. Also tell me how to show this file with sorting order by datetime.
I tried using
docName.Add(file.ModifiedBy);
property but its not available, here is the code:
public List<string> getFiles(ClientContext CContext,string INVOICENO)
{
List list = CContext.Web.Lists.GetByTitle("Documents");
CContext.Load(list);
CContext.Load(list.RootFolder);
CContext.Load(list.RootFolder.Folders);
CContext.Load(list.RootFolder.Files);
CContext.ExecuteQuery();
FolderCollection fcol = list.RootFolder.Folders;
List<string> docName = new List<string>();
foreach (Folder f in fcol)
{
if(INVOICENO==null)
{
INVOICENO = "";
}
string foldername = INVOICENO.ToString();
if (f.Name == foldername)
{
CContext.Load(f.Files);
CContext.ExecuteQuery();
FileCollection fileCol = f.Files;
foreach (File file in fileCol)
{
docName.Add(file.Name);
docName.Add(file.TimeLastModified.ToShortDateString());
}
}
}
return docName.ToList();
}
According to my testing and research, you can use CAML Query to display the files modified by the username from the SharePoint folder.
Here is an example you can refer to:(sorted by modification time in ascending order)
static void Main(string[] args)
{
var clientContext = GetonlineContext();
Web site = clientContext.Web;
List list = clientContext.Web.Lists.GetByTitle("Library Name");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Editor' /><Value Type='User'>UserName</Value></Eq></Where><OrderBy><FieldRef Name='Modified' Ascending='True' /></OrderBy></Query><ViewFields /><QueryOptions /></View>";
ListItemCollection collListItem = list.GetItems(query);
clientContext.Load(collListItem);
clientContext.ExecuteQuery();
foreach (ListItem item in collListItem)
{
Debug.WriteLine("Name:"+item["FileLeafRef"]+"\n"+"Modified"+item["Modified"]);
}
clientContext.ExecuteQuery();
}
I am trying to return all files and folders in a SharePoint library starting from a given subfolder.
If I set the FolderServerRelativeUrl on the CamlQuery to the folder i wish to start from, I can get all the list items for that given folder; however, when I try to add in camlQuery.ViewXML to recursively return items with any additional sub folders as well, I get the following exception:
Microsoft.SharePoint.Client.ServerException: 'The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.'
Code
public static IEnumerable<string> GetSharepointFiles2(string sharePointsite, string libraryName, string username, string password, string subFolders)
{
Uri filename = new Uri(sharePointsite);
string server = filename.AbsoluteUri.Replace(filename.AbsolutePath, "");
List<string> fullfilePaths = new List<string>();
using (ClientContext cxt = new ClientContext(filename))
{
cxt.Credentials = GetCreds(username, password);
Web web = cxt.Web;
cxt.Load(web, wb => wb.ServerRelativeUrl);
cxt.ExecuteQuery();
List list = web.Lists.GetByTitle(libraryName);
cxt.Load(list);
cxt.ExecuteQuery();
Folder folder = web.GetFolderByServerRelativeUrl(web.ServerRelativeUrl + subFolders);
cxt.Load(folder);
cxt.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='RecursiveAll'>
<Query>
</Query>
</View>";
camlQuery.FolderServerRelativeUrl = folder.ServerRelativeUrl;
ListItemCollection listItems = list.GetItems(camlQuery);
cxt.Load(listItems);
cxt.ExecuteQuery();
foreach (ListItem listItem in listItems)
{
if (listItem.FileSystemObjectType == FileSystemObjectType.File)
{
fullfilePaths.Add(String.Format("{0}{1}", server, listItem["FileRef"]));
}
else if (listItem.FileSystemObjectType == FileSystemObjectType.Folder)
{
Console.WriteLine(String.Format("{0}{1}", server, listItem["FileRef"]));
fullfilePaths.Add(String.Format("{0}{1}", server, listItem["FileRef"]));
}
}
}
return fullfilePaths;
}
private static SharePointOnlineCredentials GetCreds(string username, string password)
{
SecureString securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
return new SharePointOnlineCredentials(username, securePassword);
}
In terms of the threshold limit, I have tried this on a folder with only 1 file and 1 folder in (in turn that folder has 1 file only), so if the limit is default 5000, I have no idea why I'd be getting this.
Finally found a solution that works, even if it is a bit sledgehammer!
Although the folders I was looking to retrieve the items for had far less than 5000 items, the issue was the list as a whole did exceed this threshold (In this case it was about 11,000 items).
I removed the FolderServerRelativeURL attribute and then used ListItemCollectionPosition to paginate/batch up the all the items in the list. Once all the items are in a collection it can be filtered with Linq for the relevant subfolder. (CAML Query - Going around the 5000 List Item Threshold)
If anyone has a way of being more targeted with the items, I'd love to see it.
Code:
public static IEnumerable<ListItem> GetSharepointFiles2(string sharePointsite, string libraryName, string username, string password, string subFolders)
{
Uri filename = new Uri(sharePointsite);
List<ListItem> items = new List<ListItem>();
using (ClientContext cxt = new ClientContext(filename))
{
cxt.Credentials = GetCreds(username, password);
Web web = cxt.Web;
cxt.Load(web, wb => wb.ServerRelativeUrl);
cxt.ExecuteQuery();
List list = web.Lists.GetByTitle(libraryName);
cxt.Load(list);
cxt.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View Scope='Recursive'><RowLimit>5000</RowLimit></View>";
do
{
ListItemCollection listItems = list.GetItems(camlQuery);
cxt.Load(listItems);
cxt.ExecuteQuery();
items.AddRange(listItems);
camlQuery.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
} while (camlQuery.ListItemCollectionPosition != null);
var filteritems = items.Where(tt => tt.FieldValues["FileRef"].ToString().StartsWith(web.ServerRelativeUrl + subFolders));
return filteritems;
}
}
I have the code below:
using (var context = new ClientContext(URL))
{
context.Credentials = new SharePointOnlineCredentials(username, password);
Web web = context.Web;
context.Load(web.Lists, lists => lists.Include(list => list.Title, list => list.Id));
context.ExecuteQuery();
List SupportList = context.Web.Lists.GetByTitle("Support");
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem newItem = SupportList.AddItem(itemCreateInfo);
foreach (var selector in f.rtxt_select.Text.Split(','))
{
var s = selector.Split('=');
newItem[s[0].Trim()] = m.GetType().GetProperty(s[1].Trim()).GetValue(m, null);
}
newItem.Update();
context.ExecuteQuery();
f.txtMessage.AppendText("Message has been added to Sharepoint List \n ");
f.lbl_successCount.Text = (Convert.ToInt32(f.lbl_successCount.Text) + 1).ToString();
}
Everything works just fine if the username and password is correct. But Is there is a way i can validate if the user has access to the site(SharePoint Online)?
Check Web.GetUserEffectivePermissions method.
In my project I need to store the site pages locally. These pages may be of published or unpublished pages. I have tried with following code but unable to get contents of the page.
ClientContext clientcontext = new ClientContext(url);
var credentials = new SharePointOnlineCredentials(userid, SecurePass);
clientcontext.Credentials = credentials;
Web web = clientcontext.Web;
clientcontext.Load(web, website => website.Lists);
clientcontext.ExecuteQuery();
clientcontext.Load(web, website => website.Lists,
website => website.Lists.Where(
x => x.BaseTemplate == 119));
clientcontext.ExecuteQuery();
var _collection = web.Lists;
foreach (var pages in _collection)
{
clientcontext.Load(pages);
clientcontext.ExecuteQuery();
CamlQuery cq = new CamlQuery();
var pg = pages.GetItems(cq);
clientcontext.Load(pg);
clientcontext.ExecuteQuery();
foreach (var item in pg)
{
clientcontext.Load(item);
clientcontext.ExecuteQuery();
var f_webPage = clientcontext.Web.GetFileByServerRelativeUrl(item.File.ServerRelativeUrl);
clientcontext.Load(f_webPage);
clientcontext.ExecuteQuery();
}
}
How can I get site pages contents?
Thanks in advance.
In Site Pages library (list type of ListTemplateType.WebPageLibrary) the content for list item depending on the underling the content type could be extracted from:
WikiField field in case of Wiki Page
CanvasContent1 field in case of Site Page (aka "modern" page)
Example
var listTitle = "Site Pages";
var list = ctx.Web.Lists.GetByTitle(listTitle);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, icol => icol.Include( i => i["WikiField"], i => i["CanvasContent1"], i => i["FileRef"], i => i.ContentType));
ctx.ExecuteQuery();
foreach (var item in items)
{
Console.WriteLine(">>> {0}", item["FileRef"]);
switch (item.ContentType.Name)
{
case "Site Page":
Console.WriteLine(item["CanvasContent1"]);
break;
case "Wiki Page":
Console.WriteLine(item["WikiField"]);
break;
}
}
I need to use sharepoint client api in my project and list documents in folders that uploaded to sharepoint. My folders are under the link "https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/Shared%20Documents/Forms/AllItems.aspx"
using (ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/"))
{
string userName = "username";
string password = "password";
SecureString secureString = new SecureString();
password.ToList().ForEach(secureString.AppendChar);
ctx.Credentials = new SharePointOnlineCredentials(userName, secureString);
List list = ctx.Web.Lists.GetByTitle("/Shared Documents/");
CamlQuery caml = new CamlQuery();
caml.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
caml.FolderServerRelativeUrl = "/sites/blsmtekn/dyncrm/";
ListItemCollection listItems = list.GetItems(caml);
ctx.Load(listItems);
ctx.ExecuteQuery();
}
But I'm getting error like “List…does not exist at site with URL”. How can I get list of folders and files under that folders recursively.
From the top of my head I'm seeing a few mistakes: Your code states, that the name of your library is /Shared Documents/, while the name most likely is Shared Documents.
Please fix the name of your GetByTitle() call:
List list = ctx.Web.Lists.GetByTitle("Shared Documents");
The second error is, that the url to your site collection is wrong. It should be
ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/")
Additionally you can remove caml.FolderServerRelativeUrl = "/sites/blsmtekn/dyncrm/"; since that is wrong.
All in all your code should look like this:
using (ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/"))
{
string userName = "username";
string password = "password";
SecureString secureString = new SecureString();
password.ToList().ForEach(secureString.AppendChar);
ctx.Credentials = new SharePointOnlineCredentials(userName, secureString);
List list = ctx.Web.Lists.GetByTitle("Shared Documents");
CamlQuery caml = new CamlQuery();
caml.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
ListItemCollection listItems = list.GetItems(caml);
ctx.Load(listItems);
ctx.ExecuteQuery();
}