Read site page contents in Sharepoint using CSOM - c#

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

Related

how to get modifiedby property of a file for showing file details sharepoint C#

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

Unable to update "Last_x0020_Modified" in a SharePoint document

I would like to update "Last_x0020_Modified" in the SharePoint documentation.
I am unable to update with the error.
"Invalid data is being used to update the list item. The field you are trying to update may be read-only."
Is there a way to update "Last_x0020_Modified"?
using (var context = new ClientContext("URL"))
{
var passWord = new SecureString();
foreach (char c in "pass".ToCharArray())
{
passWord.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials("account", passWord);
var documents = context.Web.Lists.GetByTitle("Document");
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = false;
documents.Update();
context.ExecuteQuery();
var query = CamlQuery.CreateAllItemsQuery();
var collListItem = documents.GetItems(query);
context.Load(collListItem,
items => items.Include(
item => item.Id,
item => item.DisplayName,
item => item.ContentType,
item => item["Modified"],
item => item["Last_x0020_Modified"]
));
context.ExecuteQuery();
foreach (var listItem in collListItem.Where(item => item.ContentType.Name == "folder"))
{
listItem["Last_x0020_Modified"] = "2020/09/01T09:00:00";
}
context.ExecuteQuery();
documents.Fields.GetByInternalNameOrTitle("Last_x0020_Modified").ReadOnlyField = true;
documents.Update();
context.ExecuteQuery();
}
Best Regard.
Per my test, I got the same result as yours on my end. Looks like we cannot change the property "Last_x0020_Modified".
Besides, I found the field "Last_x0020_Modified" is a lookup field.

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

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 Online Workflow restart error (Console Application)

I frequently get requests to restart a workflow for some of my list items. I have written an application which takes library name and list item name as an input. when i try to start a workflow (StartWorkflow method) i get this error Exception from HRESULT: 0x8102009B and no inner exception. Below is my code.
Sometimes the workflow may have already been started. In that case i need to cancel the workflow and then restart.
I did lot of search on this issue. Most of the resolution is for SP 2010. We are using SP Online
clientContext.Credentials = new SharePointOnlineCredentials(Userid, Password);
var web = clientContext.Web;
List list = web.Lists.GetByTitle("listname");
clientContext.Load(list);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View><Query><OrderBy><FieldRef Name='FileLeafRef' Descending='True'/></OrderBy><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='File'>" + ListItemName + ".xml</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>";
ListItemCollection items = list.GetItems(camlQuery);
clientContext.Load(items);
clientContext.ExecuteQuery();
var id = items.Where(a => a.FieldValues["FileLeafRef"].ToString() == ListItemName + ".xml").Select(a => a.Id).FirstOrDefault();
Guid listItemID = (Guid)items.Where(a => a.FieldValues["FileLeafRef"].ToString() == ListItemName + ".xml").Select(a => a.FieldValues["GUID"]).FirstOrDefault();
WorkflowAssociationCollection wfaCollection = items.Where(a => a.FieldValues["FileLeafRef"].ToString() == ListItemName + ".xml")
.Select(a => a.ParentList.WorkflowAssociations).FirstOrDefault();
clientContext.Load(wfaCollection);
var workflowServiceManager = new WorkflowServicesManager(clientContext, web);
clientContext.Load(workflowServiceManager);
clientContext.ExecuteQuery();
InteropService workflowInteropService = workflowServiceManager.GetWorkflowInteropService();
clientContext.Load(workflowInteropService);
var wfaName = wfaCollection.Where(a => a.Enabled == true).Select(a => a.Name).FirstOrDefault();
Guid wfaId = wfaCollection.Where(a => a.Enabled == true).Select(a => a.Id).FirstOrDefault();
var initiationData = new Dictionary<string, object>();
ClientResult<Guid> resultGuid = workflowInteropService.StartWorkflow(wfaName, new Guid(), list.Id, listItemID, initiationData);
clientContext.ExecuteQuery();

Categories

Resources