How do i find the folder id of a Skydrive folder using the folder name. Or Is it possible to delete a folder in Skydrive without its folder id.
Am using Windows Phone 8 - LiveConnectClient
-Thanks
I don't think there is a search API but you can do it yourself.
This code is for 5.2 SDK but you get the idea. List the folders in the root folder. If needed list the subfolders till you find the directory.
This is to list the root:
clientFolder.GetAsync("me/skydrive/files");
And to get the ids:
foreach (IDictionary<string, object> album in data)
{
SkydriveAlbum albumItem = new SkydriveAlbum();
albumItem.ID = (string)album["id"];
}
Full code:
/// <summary>
/// Gets the root dirs from SkyDrive
/// </summary>
public void ListSkyDriveRootAlbums()
{
List<SkydriveAlbum> albums = new List<SkydriveAlbum>();
LiveConnectClient clientFolder = new LiveConnectClient(App.Session);
clientFolder.GetCompleted += (sender, e) =>
{
if (e.Error == null)
{
List<object> data = (List<object>)e.Result["data"];
foreach (IDictionary<string, object> album in data)
{
SkydriveAlbum albumItem = new SkydriveAlbum();
albumItem.Title = (string)album["name"];
albumItem.Description = (string)album["description"];
albumItem.ID = (string)album["id"];
albums.Add(albumItem);
}
if (ListAlbumsCompleted != null)
{
ListAlbumsCompleted(albums.ToArray(), e.Error);
}
}
else if (ListAlbumsCompleted != null)
{
ListAlbumsCompleted(null, e.Error);
}
};
clientFolder.GetAsync("me/skydrive/files");
}
Related
I want to create some folders in the document library in C#.
The folder structure should be as follows in the document library:
"98_Projekte" --> "Muster Mandant" --> "01 Test Subfolder"
In my C# code, I only create the sub folder "Muster Mandant" in "98_Projekte". That is correct, but I want afterwards to create new subfolders in "Muster Mandant" (see second foreach).
public static void AddFolder(ClientContext context, string[] folders)
{
Web web = context.Web;
var docLibrary = web.DefaultDocumentLibrary().RootFolder;
context.Load(docLibrary);
context.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.Folder subFolder in docLibrary.Folders)
{
if (subFolder.Name == "98_Projekte")
{
subFolder.Folders.Add("Muster Mandant");
context.ExecuteQuery();
docLibrary = subFolder;
docLibrary.Update();
}
}
foreach (Microsoft.SharePoint.Client.Folder subSubFolder in docLibrary.Folders)
{
if (subSubFolder.Name == "Muster Mandant")
{
foreach (string folder in folders)
{
subSubFolder.Folders.Add(folder);
}
}
}
context.ExecuteQuery();
}
}
Do you have any solutions?
You may check below code.
public static Folder AddSubFolder(ClientContext context, Folder ParentFolder, string folderName)
{
Folder resultFolder=ParentFolder.Folders.Add(folderName);
context.ExecuteQuery();
return resultFolder;
}
static void Main(string[] args)
{
using (var context = new ClientContext("https://domain.sharepoint.com/sites/TST/"))
{
string password = "pw";
SecureString sec_pass = new SecureString();
Array.ForEach(password.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();
context.Credentials = new SharePointOnlineCredentials("lee#domain.onmicrosoft.com", sec_pass);
Web web = context.Web;
var folders = web.DefaultDocumentLibrary().RootFolder.Folders;
context.Load(folders);
context.ExecuteQuery();
foreach (Folder subFolder in folders)
{
if (subFolder.Name == "98_Projekte")
{
Folder parent1= AddSubFolder(context,subFolder,"Muster Mandant");
AddSubFolder(context, parent1, "01 Test Subfolder");
}
}
Console.WriteLine("Done");
Console.ReadKey();
}
}
I think the problem is that your code is expecting the .Folders property to contain all folders (recursive) and instead you are just getting the direct children of the root folder. In your 2nd loop check the context of the docLibrary.Folders property/collection and see what is returned.
I'm trying to create a folder structure under a list in Sharepoint online.
I created a list called Shared1 according to this article:
http://blogs.technet.com/b/catastrophic_failure_joannav/archive/2013/10/23/how-to-create-a-custom-list-in-sharepoint-online-quot-w15-quot.aspx
And I'm using this code for trying to create an underlying structure:
using (var clientContext = new ClientContext("https://myEnv.sharepoint.com"))
{
var passWord = new SecureString();
foreach (char c in "myPSW".ToCharArray()) passWord.AppendChar(c);
clientContext.Credentials = new SharePointOnlineCredentials("myAcc#myenv.onmicrosoft.com", passWord);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
var folder = CreateFolder(clientContext.Web, "Shared1", "FolderA/SubFolderA/SubSubFolderA");
}
/// <summary>
/// Create Folder client object
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <param name="fullFolderUrl"></param>
/// <returns></returns>
public static Folder CreateFolder(Web web, string listTitle, string fullFolderUrl)
{
if (string.IsNullOrEmpty(fullFolderUrl))
throw new ArgumentNullException("fullFolderUrl");
var list = web.Lists.GetByTitle(listTitle);
return CreateFolderInternal(web, list.RootFolder, fullFolderUrl);
}
private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderUrl)
{
var folderUrls = fullFolderUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string folderUrl = folderUrls[0];
var curFolder = parentFolder.Folders.Add(folderUrl);
web.Context.Load(curFolder);
web.Context.ExecuteQuery();
if (folderUrls.Length > 1)
{
var subFolderUrl = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
return CreateFolderInternal(web, curFolder, subFolderUrl);
}
return curFolder;
}
public static Folder GetFolder(Web web, string fullFolderUrl)
{
if (string.IsNullOrEmpty(fullFolderUrl))
throw new ArgumentNullException("fullFolderUrl");
if (!web.IsPropertyAvailable("ServerRelativeUrl"))
{
web.Context.Load(web, w => w.ServerRelativeUrl);
web.Context.ExecuteQuery();
}
var folder = web.GetFolderByServerRelativeUrl(web.ServerRelativeUrl + fullFolderUrl);
web.Context.Load(folder);
web.Context.ExecuteQuery();
return folder;
}
And upon the execution I get this error:
Unhandled Exception: Microsoft.SharePoint.Client.ServerException: List 'Shared1'
does not exist at site with URL 'https://myEnv.sharepoint.com'.
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream res
ponseStream)
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
at SharepointFolderRename.Program.CreateFolderInternal(Web web, Folder parent
Folder, String fullFolderUrl) in \\vmware-host\shared folders\Documents\Visual S
tudio 2012\Projects\Trunk2015\SharepointFolderRename\Program.cs:line 84
at SharepointFolderRename.Program.Main(String[] args) in \\vmware-host\shared
folders\Documents\Visual Studio 2012\Projects\Trunk2015\SharepointFolderRename\
Program.cs:line 49
This is a print of the list in SP.
What am I missing?
The reason why you are getting those errors is related with incorrect web url specified. While your list exists on sub site Shared1, you are trying to access it on root site,the below picture illustrates it
So, the solution would be to initialize client context for the proper web site, so replace:
using (var clientContext = new ClientContext("https://myEnv.sharepoint.com/"))
{
//...
}
with
using (var clientContext = new ClientContext("https://myEnv.sharepoint.com/Shared1"))
{
//...
}
It is assumed that you want to ctreate folders for list located on
Shared1 sub site
Example
The example below demonstrates how to create the folder hierarchy in Documents library under News sub site: (https://contoso.sharepoint.com/news)
Archive
|
2009
|
09
Usage
using (var ctx = GetContext("https://contoso.sharepoint.com/news", userName, password))
{
var list = ctx.Web.Lists.GetByTitle("Documents");
var folder = list.CreateFolder("Archive/2015/09");
Console.WriteLine(folder.ServerRelativeUrl);
}
where
public static ClientContext GetContext(Uri webUri, string userName, string password)
{
var securePassword = new SecureString();
foreach (var ch in password) securePassword.AppendChar(ch);
return new ClientContext(webUri) { Credentials = new SharePointOnlineCredentials(userName, securePassword) };
}
ListExtensions.cs file:
using System;
using Microsoft.SharePoint.Client;
namespace SharePoint.ClientExtensions
{
public static class ListExtensions
{
/// <summary>
/// Create Folder in List
/// </summary>
/// <param name="list"></param>
/// <param name="folderUrl"></param>
/// <returns></returns>
public static Folder CreateFolder(this List list, string folderUrl)
{
if (string.IsNullOrEmpty(folderUrl))
throw new ArgumentNullException("folderUrl");
if (!list.IsPropertyAvailable("RootFolder"))
{
list.Context.Load(list.RootFolder);
list.Context.ExecuteQuery();
}
return CreateFolderInternal(list.RootFolder,folderUrl);
}
private static Folder CreateFolderInternal(Folder parentFolder, string folderUrl)
{
var folderUrlParts = folderUrl.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var curFolder = parentFolder.Folders.Add(folderUrlParts[0]);
parentFolder.Context.Load(curFolder);
parentFolder.Context.ExecuteQuery();
if (folderUrlParts.Length > 1)
{
var subFolderUrl = string.Join("/", folderUrlParts, 1, folderUrlParts.Length - 1);
return CreateFolderInternal(curFolder, subFolderUrl);
}
return curFolder;
}
}
}
You need to load the list in the CreateFolder method.
public static Folder CreateFolder(Web web, string listTitle, string fullFolderUrl)
{
if (string.IsNullOrEmpty(fullFolderUrl))
throw new ArgumentNullException("fullFolderUrl");
var list = web.Lists.GetByTitle(listTitle);
clientContext.Load(list);
clientCOntext.Execute();
return CreateFolderInternal(web, list.RootFolder, fullFolderUrl);
}
My outlook client has a shared folder "xxxx yyyy". However, the following code, which iterates all the folder and sub folder recursively, doesn't print out the folder. Why the code cannot get the folder?
private static void PrintAllPubFolder(ExchangeService service)
{
var folderView = new FolderView(int.MaxValue);
var findFolderResults = service.FindFolders(WellKnownFolderName.PublicFoldersRoot, folderView);
foreach (var folder in findFolderResults.Where(x => !ignore.Any(i => i == x.DisplayName)))
{
Console.WriteLine(folder.DisplayName);
PrintSubFolder(service, folder.Id, " ");
}
}
private static void PrintSubFolder(ExchangeService service, FolderId folderId, string p)
{
var folderView = new FolderView(int.MaxValue);
var findFolderResults = service.FindFolders(folderId, folderView);
foreach (var folder in findFolderResults.Where(x => !ignore.Any(i => i == x.DisplayName)))
{
Console.WriteLine("{0}{1}", p, folder.DisplayName);
PrintSubFolder(service, folder.Id, p + " ");
}
}
If your using Exchange 2010 or later don't use
var folderView = new FolderView(int.MaxValue);
Throttling will limit the results returned to 1000 so if you expect more the 1000 entries to be return then you'll need to page the results. However it doesn't make much sense to enumerate through every public folder to get the target look at the method in the following link
Searching Of Folders in Public Folders by giving its PATH Name
if the folder is in your mailbox then just do a search for that based on the name eg
FolderView ffView = new FolderView(1000);
ffView.Traversal = FolderTraversal.Deep;
SearchFilter fSearch = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "xxxx yyyy");
FindFoldersResults ffResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, fSearch, ffView);
Cheers
Glen
I need to retrieve items from the 'Inbox\test\final' Exchange folder using EWS. The folder is provided by a literal path as written above. I know I can split this string into folder names and recursively search for the necessary folder, but is there a more optimal way that can translate a string path into a folder instance or folder ID?
I'm using the latest EWS 2.0 assemblies. Do these assemblies provide any help, or am I stuck with manual recursion?
You could use an extended property as in this example
private string GetFolderPath(ExchangeService service, FolderId folderId)
{
var folderPathExtendedProp = new ExtendedPropertyDefinition(26293, MapiPropertyType.String);
var folderPropSet = new PropertySet(BasePropertySet.FirstClassProperties) { folderPathExtendedProp };
var folder = Folder.Bind(service, folderId, folderPropSet);
string path = null;
folder.TryGetProperty(folderPathExtendedProp, out path);
return path?.Replace("\ufffe", "\\");
}
Source: https://social.msdn.microsoft.com/Forums/en-US/e5d07492-f8a3-4db5-b137-46e920ab3dde/exchange-ews-managed-getting-full-path-for-a-folder?forum=exchangesvrdevelopment
Since Exchange Server likes to map everything together with Folder.Id, the only way to find the path you're looking for is by looking at folder names.
You'll need to create a recursive function to go through all folders in a folder collection, and track the path as it moves through the tree of email folders.
Another parameter is needed to track the path that you're looking for.
public static Folder GetPathFolder(ExchangeService service, FindFoldersResults results,
string lookupPath, string currentPath)
{
foreach (Folder folder in results)
{
string path = currentPath + #"\" + folder.DisplayName;
if (folder.DisplayName == "Calendar")
{
continue;
}
Console.WriteLine(path);
FolderView view = new FolderView(50);
SearchFilter filter = new SearchFilter.IsEqualTo(FolderSchema.Id, folder.Id);
FindFoldersResults folderResults = service.FindFolders(folder.Id, view);
Folder result = GetPathFolder(service, folderResults, lookupPath, path);
if (result != null)
{
return result;
}
string[] pathSplitForward = path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
string[] pathSplitBack = path.Split(new[] { #"\" }, StringSplitOptions.RemoveEmptyEntries);
string[] lookupPathSplitForward = lookupPath.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
string[] lookupPathSplitBack = lookupPath.Split(new[] { #"\" }, StringSplitOptions.RemoveEmptyEntries);
if (ArraysEqual(pathSplitForward, lookupPathSplitForward) ||
ArraysEqual(pathSplitBack, lookupPathSplitBack) ||
ArraysEqual(pathSplitForward, lookupPathSplitBack) ||
ArraysEqual(pathSplitBack, lookupPathSplitForward))
{
return folder;
}
}
return null;
}
"ArraysEqual":
public static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1, a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
I do all the extra array checking since sometimes my clients enter paths with forward slashes, back slashes, starting with a slash, etc. They're not tech savvy so let's make sure the program works every time!
As you go through each directory, compare the desired path to the iterated path. Once it's found, bubble up the Folder object that it's currently on. You'll need to create a search filter for that folder's id:
FindItemsResults<item> results = service.FindItems(foundFolder.Id, searchFilter, view);
Loop through the emails in results!
foreach (Item item in results)
{
// do something with item (email)
}
Here's my recursive descent implementation, which attempts to fetch as little information as possible on the way to the target folder:
private readonly FolderView _folderTraversalView = new FolderView(1) { PropertySet = PropertySet.IdOnly };
private Folder TraceFolderPathRec(string[] pathTokens, FolderId rootId)
{
var token = pathTokens.FirstOrDefault();
var matchingSubFolder = _exchangeService.FindFolders(
rootId,
new SearchFilter.IsEqualTo(FolderSchema.DisplayName, token),
_folderTraversalView)
.FirstOrDefault();
if (matchingSubFolder != null && pathTokens.Length == 1) return matchingSubFolder;
return matchingSubFolder == null ? null : TraceFolderPathRec(pathTokens.Skip(1).ToArray(), matchingSubFolder.Id);
}
For a '/'-delimited path, it can be called as follows:
public Folder TraceFolderPath(string folderPath)
{ // Handle folder names with '/' in them
var tokens = folderPath
.Replace("\\/", "<slash>")
.Split('/')
.Select(t => t.Replace("<slash>", "/"))
.ToArray();
return TraceFolderPathRec(tokens, WellKnownFolderName.MsgFolderRoot);
}
No, you don't need recursion and you efficiently go straight to the folder. This uses the same extended property as Tom, and uses it to apply a search filter:
using Microsoft.Exchange.WebServices.Data; // from nuget package "Microsoft.Exchange.WebServices"
...
private static Folder GetOneFolder(ExchangeService service, string folderPath)
{
var propertySet = new PropertySet(BasePropertySet.IdOnly);
propertySet.AddRange(new List<PropertyDefinitionBase> {
FolderSchema.DisplayName,
FolderSchema.TotalCount
});
var pageSize = 100;
var folderView = new FolderView(pageSize)
{
Offset = 0,
OffsetBasePoint = OffsetBasePoint.Beginning,
PropertySet = propertySet
};
folderView.Traversal = FolderTraversal.Deep;
var searchFilter = new SearchFilter.IsEqualTo(ExchangeExtendedProperty.FolderPathname, folderPath);
FindFoldersResults findFoldersResults;
var baseFolder = new FolderId(WellKnownFolderName.MsgFolderRoot);
var localFolderList = new List<Folder>();
do
{
findFoldersResults = service.FindFolders(baseFolder, searchFilter, folderView);
localFolderList.AddRange(findFoldersResults.Folders);
folderView.Offset += pageSize;
} while (findFoldersResults.MoreAvailable);
return localFolderList.SingleOrDefault();
}
...
public static class ExchangeExtendedProperty
{
/// <summary>PR_FOLDER_PATHNAME String</summary>
public static ExtendedPropertyDefinition FolderPathname { get => new ExtendedPropertyDefinition(0x66B5, MapiPropertyType.String); }
}
The path will need to be prefixed with a backslash, ie. \Inbox\test\final.
How to get all folders name of gmail using ImapX lib?
I read in http://hellowebapps.com/2010-02-09/imapx-net-library-to-manage-imap-folders/ but not found get all folder part.
here is how you get the list of all folders...
FolderCollection folders = client.GetFolders();
foreach (Folder myfolder in folders)
{
MessageBox.Show(myfolder.Name);
}
then use the name with:
ImapX.MessageCollection messages = client.Folders["Spam"].Search("ALL", true);
note that folder name is a case sensitive...
You can iterate the SubFolder collection and can get all of those gamail folders and thier path. An example:
var client = new ImapClient(...);
client.Connection();
client.LogIn(...);
foreach (var item in WalkFolderTree(client.Folders))
{
Console.WriteLine(item.FolderPath);
}
client.LogOut();
You have to custom implement the traversal code like:
public IEnumerable<Folder> WalkFolderTree(FolderCollection folders)
{
foreach (var item in folders)
{
if (item.HasChildren)
{
WalkFolderTree(item.SubFolder);
}
yield return item;
}
}
Then it will list all of the folders like:
INBOX
...
[Gmail]
[Gmail]/All Mail
[Gmail]/Drafts
[Gmail]/Sent Mail
[Gmail]/Spam
[Gmail]/Starred
[Gmail]/Trash
Here's how:
public List<string> getMailboxes(string emailAddress, string emailPassword)
{
var client = new ImapClient("imap.gmail.com", 993, true, true);
if (client.Connect())
{
if (client.Login(emailAddress, emailPassword))
{
//get all parent folers
var folders = client.Folders;
foreach (var parentFolder in folders)
{
//get parent folder path
var parentPath = parentFolder.Path;
//check if every parent folder has subfolder
if (parentFolder.HasChildren)
{
var subfolders = parentFolder.SubFolders;
foreach(var subfolder in subfolders)
{
var subPath = subfolder.Path;
}
}
}
}
}
}