Sharepoint get content from list - c#

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

Related

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

Check if user has access to SharePoint Online site

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.

Sharepoint - uploading files with column values can't load Taxonomy fields in target

I am trying to transfer files from one document library on one farm to another. Since both are accessible from same network, I thought of getting column values from source and directly add it into a item on destination. Also upload the file along with the item.
List list = ccSource.Web.Lists.GetByTitle("Source Library");
ccSource.ExecuteQuery(); // ccSource is initialized with source Site collection
CamlQuery query = new CamlQuery();
ListItemCollection itemCollection = list.GetItems(CamlQuery.CreateAllItemsQuery()); //Query can also be selective
ccSource.Load(list);
ccSource.Load(itemCollection);
ccSource.ExecuteQuery();
ccSource.Load(ccSource.Web);
string[] coloumnsList = System.IO.File.ReadAllLines(#"E:\Coloumns.txt");
foreach (ListItem item in itemCollection)
{
ClientContext ccTarget. = new ClientContext("http://TargetSC/sites/mysite");
ccTarget.Credentials = new NetworkCredential("username", "pass", "domain");
ccTarget.ExecuteQuery();
var targetList = ccTarget.Web.Lists.GetByTitle("TargetLibrary");
string diskFilePath = #"E:\downloadedFile.docx"; //I have skipped the download code
var fileInfo1 = new FileCreationInformation
{
Url = System.IO.Path.GetFileName(diskFilePath),
Content = System.IO.File.ReadAllBytes(diskFilePath),
Overwrite = true
};
var file = targetList.RootFolder.Files.Add(fileInfo1);
var itemTar = file.ListItemAllFields;
//update list values
foreach (var allFields in item.FieldValues)
{
if (allFields.Key == "FileLeafRef" || checkColoumn(coloumnsList,allFields.Key))
itemTar[allFields.Key] = allFields.Value;
}
itemTar.Update();
ccTarget.ExecuteQuery(); //Exception here
}
public static bool checkColoumn(string[] arr,string query)
{
bool flag = false;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].Equals(query))
{flag = true; break;}
}
return flag;
}
I am getting exception:
The given guid does not exist in the term storeon
ccTarget.exceuteQuery()

Reading existing field value from SharePoint Custom List fails

I am trying to read the value of a particular field in a SharePoint Custom List.
The Custom List has the following fields: Field1, Field2 and Field3
When I call the code below:
public static string GetLastTargetColumnValue(string sharePointSiteUrl, string sharePointListName, string targetColumnName)
{
string targetColumnValue = string.Empty;
using (var clientContext = new ClientContext(sharePointSiteUrl))
{
clientContext.Credentials = new NetworkCredential("userName", "password");
var list = clientContext.Web.Lists.GetByTitle(sharePointListName);
var query = CamlQuery.CreateAllItemsQuery(100);
var items = list.GetItems(query);
clientContext.Load(items);
clientContext.ExecuteQuery();
var listItem = items.Last();
foreach (var fieldValue in listItem.FieldValues)
{
Console.WriteLine(fieldValue.Key + ":" + fieldValue.Value + Environment.NewLine);
}
}
targetColumnValue = listItem[targetColumnName] as string;
return targetColumnValue;
}
The error message is:
Additional information: 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.
The fields which are displayed in the foreach show "Field1" and "Field2". Do I have to explicitly request "Field3". If yes how?
I had to get the internal name before querying the value for some reason. Here is the code that worked:
public static string GetLastTargetColumnValue(string sharePointSiteUrl, string sharePointListName, string targetColumnName)
{
string targetColumnValue = string.Empty;
using (var clientContext = new ClientContext(sharePointSiteUrl))
{
clientContext.Credentials = new NetworkCredential("userName", "password");
var list = clientContext.Web.Lists.GetByTitle(sharePointListName);
var field = list.Fields.GetByInternalNameOrTitle(targetColumnName);
var textField = clientContext.CastTo<FieldText>(field);
var query = CamlQuery.CreateAllItemsQuery(100);
var items = list.GetItems(query);
clientContext.Load(textField);
clientContext.Load(items);
clientContext.ExecuteQuery();
var listItem = items.Last();
targetColumnValue = listItem[textField.InternalName] as string;
}
return targetColumnValue;
}

C# client object

I want to read a specific SharePoint list into a datatable. I am struggeling to read the Lookup Values.
Example:
Customer list, each customer is assigned to a team member. The Team members are a lookup of the Team member list.
I have the following questions:
1.) How can I get the Information which list is linked to this lookup field?
2.) How can read the field, gets the value or the index?
I added my function below, many thanks for helping a desperate novice in SharePoint...
Regards
Volker
public System.Data.DataTable ReadDatafromSPList(ClientContext clientContext, string ListName, string ViewName)
{
Web site = clientContext.Web;
List list = site.Lists.GetByTitle(ListName);
View view = list.Views.GetByTitle(ViewName);
ViewFieldCollection viewFields = view.ViewFields;
clientContext.Load(view);
clientContext.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = view.ViewQuery;
ListItemCollection ListColletion = list.GetItems(camlQuery);
clientContext.Load(list);
clientContext.Load(ListColletion);
clientContext.Load(viewFields);
clientContext.ExecuteQuery();
string[] headers = view.ViewFields.ToArray();
System.Data.DataTable dTable = new System.Data.DataTable();
foreach (string header in headers)
{
dTable.Columns.Add(header);
}
string str="";
foreach (ListItem item in ListColletion)
{
dTable.Rows.Add(dTable.NewRow());
foreach (string header in headers)
{
try
{
str = item[header].ToString();
if (str == "Microsoft.SharePoint.Client.FieldLookupValue")
{
//??????????????????
//??????????????????
}
dTable.Rows[dTable.Rows.Count - 1][header] = str;
}
catch
{
dTable.Rows[dTable.Rows.Count - 1][header] = "";
}
}
}
return dTable;
}
Do try this..
ClientContext context = new ClientContext(ServerText.Text);
List list = context.Web.Lists.GetByTitle("Tasks");
CamlQuery query = new CamlQuery();
query.ViewXml = "<View/>";
ListItemCollection items = list.GetItems(query);
context.Load(list);
context.Load(items);
context.ExecuteQuery();
DataTable table = new DataTable();
table.Columns.Add("Id");
table.Columns.Add("Title");
foreach (ListItem item in items)
table.Rows.Add(item.Id, item["Title"]);

Categories

Resources