Copying files across site collections NOT working with app credentials, Any Idea?

Brass Contributor

Below code is working with user credentials for moving files across site collections. But when the user credentials are replaced with app credentials (ClientID,ClientSecret), it is throwing unauthorized 401 access.

 

Tried giving FullControl access at sitecollection and site level. No luck.

 

Please provide your input, if anybody has solved this issue.

 

public static void CopyDocuments()
{
	var login = "<user@tenant>.onmicrosoft.com";
	var password = "<password>";
	string srcUrl="https://xxx.sharepoint.com/sites/site1";
	string destUrl="https://xxx.sharepoint.com/sites/site2";
	string srcLibrary="library1"; 
	string destLibrary="library1";
	
	var securePassword = new SecureString();
	foreach (char c in password)
	{
		securePassword.AppendChar(c);
	}

	var onlineCredentials = new SharePointOnlineCredentials(login, securePassword);

	// set up the src client
	SP.ClientContext srcContext = new SP.ClientContext(srcUrl);
	srcContext.Credentials = onlineCredentials;

	// set up the destination context (in your case there is no needs to create a new context, because it would be the same library!!!!)
	SP.ClientContext destContext = new SP.ClientContext(destUrl);
	destContext.Credentials = onlineCredentials;


	// get the list and items
	SP.Web srcWeb = srcContext.Web;
	SP.List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
	SP.ListItemCollection col = srcList.GetItems(new SP.CamlQuery());
	srcContext.Load(col);
	srcContext.ExecuteQuery();

	// get the new list
	SP.Web destWeb = destContext.Web;
	destContext.Load(destWeb);
	destContext.ExecuteQuery();

	foreach (var doc in col)
	{
		try
		{
			if (doc.FileSystemObjectType == SP.FileSystemObjectType.File)
			{
				// get the file
				SP.File f = doc.File;
				srcContext.Load(f);
				srcContext.ExecuteQuery();

				// build new location url
				string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + f.Name;

				// read the file, copy the content to new file at new location
				SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
				SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
			} 

			if (doc.FileSystemObjectType == SP.FileSystemObjectType.Folder)
			{
				// load the folder
				srcContext.Load(doc);
				srcContext.ExecuteQuery();

				// get the folder data, get the file collection in the folder
				SP.Folder folder = srcWeb.GetFolderByServerRelativeUrl(doc.FieldValues["FileRef"].ToString());
				SP.FileCollection fileCol = folder.Files;

				// load everyting so we can access it
				srcContext.Load(folder);
				srcContext.Load(fileCol);
				srcContext.ExecuteQuery();

				foreach (SP.File f in fileCol)
				{
					// load the file
					srcContext.Load(f);
					srcContext.ExecuteQuery();

					string[] parts = null;
					string id = null;

					if (srcLibrary == "My Files")
					{
						// these are doc sets
						parts = f.ServerRelativeUrl.Split('/');
						id = parts[parts.Length - 2];
					}
					else
					{
						id = folder.Name;
					}

					// build new location url
					string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + id + "/" + f.Name;

					// read the file, copy the content to new file at new location
					SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
					SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
				}
			}
		}
		catch (Exception ex)
		{
			Log("File Error = " + ex.ToString());
		}
	}
}
2 Replies