Get document libraries in SharePoint WebSite - c#

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();
}

Related

C#.Net Download contents of SharePoint Online Folder to network drive

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();

C# Sharepoint.Client - Return all files and folders from a given subfolder

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;
}
}

Sharepoint get content from list

Hi i try to write a little application for sharepoint 2013 where we can backup our projects on an SQL Server. Now i try to loop trough all projects on sharepoint so i can get the content of the fields. Like country = austria.
I tried to follow this guide but had no luck: https://msdn.microsoft.com/en-us/library/office/fp179912.aspx
Here is that what i got:
//Loads only a Projeclist from sharepoint
public SPpowerPlantList loadProjectFromSharePoint()
{
SPpowerPlantList pplist = new SPpowerPlantList();
ClientContext context = new ClientContext(powerPlantSite);
Web web = context.Web;
context.Load(web.Lists);
context.ExecuteQuery();
foreach (List list in web.Lists)
{
SPpowerPlant pp = new SPpowerPlant();
//Stuff like this one should work but dont....
pp.country = list.country
}
return pplist;
}
Any advice would be great and sorry for my english
EDIT: SPpowerPlantList should be a List of all Projects of the Project-List from Sharepoint. And the loadProjectsFromSharepoint is supposed to get a list of Projects wich the i can start to add the values to the sql Server. Stuff like SQL Table value = Sharepoint Field Value.
EDIT2 So the access to the files now work for a few fields but know i get an The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested exeption.
Here is the new code: (some fields work like currency)
//Loads only a Projeclist from sharepoint
public SPpowerPlantList loadProjectFromSharePoint()
{
SPpowerPlantList powerPlantList = new SPpowerPlantList();
ClientContext context = new ClientContext(powerPlantSite);
List powerPlantsList = context.Web.Lists.GetByTitle("Power Plants");
CamlQuery query = CamlQuery.CreateAllItemsQuery();
query.ViewXml = #"<View><Query> </Query></View>";
ListItemCollection items = powerPlantsList.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem listItem in items)
{
SPpowerPlant powerPlant = new SPpowerPlant();
powerPlant.projectName = listItem["Project"].ToString();
powerPlant.location = listItem["Loacation"].ToString();
powerPlant.country = listItem["Country"].ToString();
powerPlant.currency = listItem["Currency"].ToString();
powerPlant.shortName = listItem["Short Name"].ToString();
powerPlant.spaceUrl = listItem["Space"].ToString();
powerPlant.numberOfWtgs = Convert.ToInt32(listItem["Number of WTGs"]);
powerPlant.mwWtg = Convert.ToDouble(listItem["MW WTG"]);
powerPlant.mwTotal = Convert.ToDouble(listItem["MW Total"]);
powerPlant.projectShareWeb = Convert.ToDouble(listItem["Project Share "]);
powerPlant.mwWeb = Convert.ToDouble(listItem["MW "]);
powerPlant.phaseDescription = listItem["Phase Description"].ToString();
powerPlant.projectProgress = Convert.ToDouble(listItem["Project Progress"]);
powerPlant.mwDeveloped = Convert.ToDouble(listItem["MW developed"]);
powerPlant.possibleWtgTypes = listItem["Possible WTG Types"].ToString();
powerPlant.hubHeight = listItem["Hub Height"].ToString();
powerPlant.allPermits = Convert.ToDateTime(listItem["All Permits"]);
powerPlant.cod = Convert.ToDateTime(listItem["COD"]);
powerPlant.projectManager = listItem["Project manager"].ToString();
powerPlant.technology = listItem["Technology"].ToString();
powerPlant.state = listItem["State"].ToString();
powerPlant.stateSince = Convert.ToDateTime(listItem["State since"]);
powerPlant.visibility = listItem["Visibillity"].ToString();
powerPlant.phase = listItem["Phase"].ToString();
powerPlant.phaseNumber = listItem["Phase Number"].ToString();
//Console.WriteLine(listItem["Currency"]);
powerPlantList.Add(powerPlant);
}
return powerPlantList;
}
I tied it with an lambda expression but no success.
Well the problem was that my listitem["names"] where not correct.
To get that stuff to work you need to go to the sharepoint site and look at the link when you sort it there you see the right name for the listitem.
New and working form:
//Loads only a Projeclist from sharepoint
public SPpowerPlantList loadProjectFromSharePoint()
{
SPpowerPlantList powerPlantList = new SPpowerPlantList();
ClientContext context = new ClientContext(powerPlantSite);
List powerPlantsList = context.Web.Lists.GetByTitle("Power Plants");
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
//query.ViewXml = #"<View><Query> </Query></View>";
ListItemCollection items = powerPlantsList.GetItems(query);
//context.Load(web.Lists,
// lists => lists.Include(list => list.Title, // For each list, retrieve Title and Id.
// list => list.Id,
// list => list.Description));
context.Load(items);
context.ExecuteQuery();
foreach (ListItem listItem in items)
{
SPpowerPlant powerPlant = new SPpowerPlant();
powerPlant.projectName = listItem["Title"].ToString();
powerPlant.location = listItem["Location"].ToString();
powerPlant.country = listItem["Country"].ToString();
powerPlant.currency = listItem["Currency"].ToString();
powerPlant.shortName = listItem["Short_x0020_Name"].ToString();
powerPlant.spaceUrl = listItem["Space"].ToString();
powerPlant.numberOfWtgs = Convert.ToInt32(listItem["Number_x0020_of_x0020_WTGs"]);
//Console.WriteLine(listItem[""]);
//powerPlantList.Add(powerPlant);
}
return null;
}

Getting The Proper Name Value Instead Of Microsoft.SharePoint.Client.FieldUserValue

I am using the following code to get users from a SharePoint list:
private ClientContext clientContext = new ClientContext(siteUrl);
private SP.List oList = clientContext.Web.Lists.GetByTitle("SharePoint List");
private CamlQuery camlQuery = new CamlQuery();
private ListItemCollection collListItem = oList.GetItems(camlQuery);
private ArrayList names = new ArrayList();
clientContext.Load(collListItem, items => items.Include(
item => item["UserNames"]));
clientContext.ExecuteQuery();
foreach (ListItem oListItem in collListItem)
{
titles.Add(oListItem["UserNames"]);
}
I am retrieving data from another columns, too, and I get those data just fine. But when it comes to names, the return value is the Microsoft.SharePoint.Client.FieldUserValue.
Any suggestions on how to get the actual usernames?
It's supposed to return FieldUserValue, you can get the users name or ID from the object. Here's a quick example:
FieldUserValue user = (FieldUserValue)listItem["Author"];
string name = user.LookupValue;

SharePoint Search query

I have a word (docx) document stored on the OneDrive for business. It has a structure like :
<title>
Book Title
</title>
<author>
High
</author>
And then I use Microsoft.SharePoint.Client for searching title and author
var targetSite = new Uri("https://my-site.sharepoint.com");
var login = "login";
var password = "pass";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
var onlineCredentials = new SharePointOnlineCredentials(login, securePassword);
using (ClientContext clientContext = new ClientContext(targetSite))
{
clientContext.Credentials = onlineCredentials;
var query = new KeywordQuery(clientContext);
query.QueryText = "<title></title><author></author>";
var searchExecutor = new SearchExecutor(clientContext);
var result = searchExecutor.ExecuteQuery(query);
clientContext.ExecuteQuery();
}
But it does not work. it returns only word title and author. What am I doing wrong?
Syntax should follow the Keyword Query Language specification (you're using KeywordQuery)
Keyword Query Language (KQL) syntax reference
For what you ask you should use something like
query.QueryText = "Author:John AND Title:Test*";

Categories

Resources