How can I download the list item versions - c#

My question is about sharepoint online.
In my project I want to download the list item with its versions. I am able to download the current list item version but not able to download its version. I have referred this answer which shows how to calculate the Canonical and Revision paths. But while fetching the data I am getting error as
The remote server returned an error: (403) Forbidden.
and in response header getting value as "Access denied. Before opening files in this location%2c you must first browse to the web site and select the option to login automatically."
string url = "https://test.sharepoint.com/teams/Mycompany";
ScureString f_SecurePass = new SecureString();
foreach (char ch in password)
f_SecurePass.AppendChar(ch);
clientcontext = new ClientContext(url);
var credentials = new SharePointOnlineCredentials(userid, f_SecurePass);
clientcontext.Credentials = credentials;
Web web = clientcontext.Web;
clientcontext.Load(web, website => website.Lists);
clientcontext.ExecuteQuery();
CamlQuery camlQ = new CamlQuery();
camlQ.ViewXml = "<View><Query><Where><Geq><FieldRef Name='ID'/>" +
"<Value Type='Number'>0</Value></Geq></Where></Query><RowLimit>100</RowLimit></View>";
var cq = _list.GetItems(camlQ);
clientcontext.Load(cq, items => items.Include(item => item.Id,
item=>item.EffectiveBasePermissionsForUI,
item=>item.EffectiveBasePermissions));
clientcontext.ExecuteQuery();
var itm = _list.GetItemById(itemid);
clientcontext.Load(itm, r => r.Id, r => r.DisplayName);
clientcontext.ExecuteQuery();
foreach (FileVersion itemVersion in itm.File.Versions)
{
int size = itemVersion.Size;
string versionlbl = itemVersion.VersionLabel;
string newversion = url + itemVersion.Url;
System.WebClient client = new System.Net.WebClient();
client.Credentials = new NetworkCredential(userid, f_SecurePass);
System.IO.Stream Data = client.OpenRead(newversion);// Throws exception
}
How can I download the list item versions?
UPDATE: If I try to download file version by using
File.OpenBinaryDirect(clientcontext, newversion);
it throws following error
Message = "Specified argument was out of the range of valid values.\r\nParameter name: serverRelativeUrl"

I am able to download file version using update CSOM apis.
Please refer
https://social.msdn.microsoft.com/Forums/en-US/802ecc6f-4a4d-4933-bf54-e68e5882203b/how-can-i-download-the-list-item-versions?forum=appsforsharepoint

Related

C# Sharepoint 365 online returns "unauthorized"

I am trying to connect to a Sharepoint site which I can open & navigate in a browser, so I do have permissions. But in my .NET Framework 4.7.2 Console app, I am getting "401 unauthorized". What am I missing? I am using the "Microsoft.SharePoint.Client.Online.CSOM" nuget package, not sure if that's the right one, but only there I had the "SharePointOnlineCredentials" which other posts recommend to use.
var siteUrl = "https://mycompany.sharepoint.com";
var context = new ClientContext(siteUrl);
var securePassword = new NetworkCredential("", "mypw").SecurePassword;
context.Credentials = new SharePointOnlineCredentials("myusername#mydomain", securePassword);
var web = context.Web;
context.Load(web);
context.ExecuteQuery(); // 401 UNAUTHORIZED
When I am using the "Microsoft.SharePointOnline.CSOM" package instead, I am getting this error:
"Cannot contact web site 'https://mycompany.sharepoint.com/' or the web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response headers are 'X-SharePointHealthScore=0, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically"
Until now, I couldn't find anything that helped.
Do I need to register the app in Azure AD or is that only needed for .NET Standard?
It's now working with the "PnP.Framework" nuget package and this code:
var credentials = new System.Net.NetworkCredential("myusername#mydomain", "mypw");
var authManager = new AuthenticationManager(credentials.UserName, credentials.SecurePassword);
using (var context = authManager.GetContext("https://mycompany.sharepoint.com"))
{
var web = context.Web;
context.Load(web, w => w.Id, w => w.Title, w => w.Url);
context.ExecuteQuery();
}

How to fix 'operation has timed out' while connecting to sharepoint on Office 365 using C#

"Operation has timed out" error while connecting to Office 365 Sharepoint from asp.net web application
I have tried finding answers and implementing solutions like below:
How to connect to SharePoint on Office 365 with CSOM from C#?
Also some blogs suggested making an asynchronous query, which does not throw error but also does not give any results.
Also tried setting timeout property without any help.
Below is my code:
SharePointOnlineCredentials networkCredential = new
SharePointOnlineCredentials(SharePointUser, SharePointPassword);
Context = new ClientContext(SharePointURL);
Context.Credentials = networkCredential;
Web = Context.Web;
Context.Load(Web);
Context.ExecuteQuery();`
Also, strangely I am able to connect and get data using Console application, but I need to get this working in web application.
After a lot of search I realized that we need proxy to connect to Sharepoint Online and implemented following code to achieve
clientContext.ExecutingWebRequest += (s, e) =>
{
e.WebRequestExecutor.WebRequest.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
};
Add clientContext.RequestTimeout = -1 in the code, the code below for your reference.
string siteUrl = "https://tenant.sharepoint.com/sites/lz";
string userName = "lz#tenant.onmicrosoft.com";
string password = "xxx";
var securePassword = new SecureString();
foreach (char c in password.ToCharArray()) securePassword.AppendChar(c);
using (ClientContext clientContext = new ClientContext(siteUrl))
{
clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
clientContext.RequestTimeout = -1;
var web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
}

Read List:The remote server returned an error: (401) Unauthorized

I'm trying to read a list in project online with a c# app
So here my code:
ClientContext clientContext = new ClientContext(client.activeProfileUrl.ToString());
List announcementsList = clientContext.Web.Lists.GetByTitle("GetUrl");
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
ListItemCollection items = announcementsList.GetItems(query);
clientContext.Load(items);
clientContext.ExecuteQuery();
foreach (ListItem listItem in items)
{
logUtil.writeLine("Title: " + listItem["Title"]);
}
So my client.activeprofile returns me the url of the environement where my user is connected (it's working well) but when I arrived at the line :clientContext.ExecuteQuery();
I get an error 401
Any idea of what I should do?
Thanks
I think you must set credentials for ClientContext.
Please see this link:
https://www.c-sharpcorner.com/article/connect-to-sharepoint-2013-online-using-csom-with-console-ap/
I think it will be what you want.
clientContext.Credentials = new SharePointOnlineCredentials(userName,password);

Extracting folder/sub folder name from SharePoint document library URL

I'm newbie to Sharepoint and currently using Sharepoint Online. I'm in need of retrieving files under a sharepoint document library in C#.
We have couple of document library urls as follows:
https://customer1.sharepoint.com/DocumentFolder/Forms/AllItems.aspx
https://customer2.sharepoint.com/sites/sitename/DocumentFolder/SubFolder/Forms/AllItems.aspx
I need to extract DocumentFolder name in case of URL 1 above, and DocumentFolder/SubFolder name in case of URL 2
Using Sharepoint REST service, I then would like to list files under DocumentFolder :
http://site url/_api/web/GetFolderByServerRelativeUrl('/DocumentFolder')
The challenge I have is to extract the DocumentFolder for the above URLs, as I could not find any API/method call to extract the DocumentFolder. I could try regex on the url, but it'll be helpful, if there is a right way to extract the DocumentFolder/SubFolder, that will be helpful.
We can use CSOM C# with CAML query to achieve it, set the view as < View Scope='RecursiveAll'>, thus gets the documents from root folder and its sub folders.
string targetSiteURL = #"https://xxx.sharepoint.com/sites/sitename";
var login = "xxx#xxx.onmicrosoft.com";
var password = "xxx";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(login, securePassword);
ClientContext ctx = new ClientContext(targetSiteURL);
ctx.Credentials = onlineCredentials;
List list = ctx.Web.Lists.GetByTitle("Documents");
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='RecursiveAll'><Query></Query></View>";
camlQuery.FolderServerRelativeUrl = folder.ServerRelativeUrl;
ListItemCollection listItems = list.GetItems(camlQuery);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
foreach (var item in listItems)
{
if (item.FileSystemObjectType == FileSystemObjectType.File)
{
// This is a File
}
else if (item.FileSystemObjectType == FileSystemObjectType.Folder)
{
// This is a Folder
}
}
More information for your reference:
http://www.sharepointpals.com/post/How-to-Get-All-the-Files-within-a-Folder-using-CAML-Query-in-SharePoint-Office-365-using-C-CSOM

C# CSOM Sharepoint Access with Tokens

I have been really struggling with getting Access Tokens working with our Sharepoint site and still no luck.
The problem is when I access our site using the SharepointOnlineCredentials it works fine, well I can query the sharepoint as follows and this works but I want to use the new token stuff that just doesn't work for me
using (ClientContext context = new ClientContext(sharepointSiteUrl))
{
context.Credentials = GetCredentials();
var web = context.Web;
context.Load(web, w => w.Title);
context.ExecuteQuery();
if (context.Web.IsPropertyAvailable("Title"))
{
Console.WriteLine("Found title");
}
Console.WriteLine("Title: {0}", web.Title);
}
private static SharePointOnlineCredentials GetCredentials()
{
SecureString password = new SecureString();
foreach (char c in "MyPassword".ToCharArray()) password.AppendChar(c);
return new SharePointOnlineCredentials("myname#mycompany.com", password);
}
So now for the code that doesn't work
authContext = new AuthenticationContext(authority, new FileCache());
ClientCredential clientCredentials = new ClientCredential(clientId, clientSecret);
AuthenticationResult authenticationResult = authContext.AcquireToken(resource, clientCredentials);
Console.WriteLine("Token Type: {0} \nExpires: {1} \nToken: {2}", authenticationResult.AccessTokenType, authenticationResult.ExpiresOn, authenticationResult.AccessToken);
using (ClientContext context = TokenHelper.GetClientContextWithAccessToken(sharepointSiteUrl, authenticationResult.AccessToken))
{
var web = context.Web;
context.Load(web);
context.ExecuteQuery();
if (context.Web.IsPropertyAvailable("Title"))
{
Console.WriteLine("Found title");
}
Console.WriteLine("Title: {0}", web.Title);
}
Now when I run this the web.Title throws an error and the context.Web display 'Cannot find the method on the object instance.'
The web.Title in the debugger also states 'The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.'
I really would love some help with this as it's turned impossible for me. Thanks :)
Do I need to be aware or granting access somewhere else? as its strange that the first one works!
In the first example you are explicitly requesting the Title property from the CSOM end-point:
context.Credentials = GetCredentials();
var web = context.Web;
context.Load(web, w => w.Title); // explicitly requesting the Title property
context.ExecuteQuery();
Whereas in the second example there is no context.Load(web, w => w.Title);
Maybe this is the issue?

Categories

Resources