2011-09-28 22 views
7

ho la seguente struttura cartella Posta in arrivo:Trova tutte le sottocartelle della cartella Posta in arrivo utilizzando EWS

Inbox 
--ABC 
----ABC 2 
----ABC 3 
--XYZ 
----XYZ 2 
--123 
----123 A 
----123 B 
----123 C 

sto utilizzando Servizi Web Exchange e il seguente codice per trovare il bambino cartelle della cartella Posta in arrivo:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010); 

service.AutodiscoverUrl("[email protected]"); 
Mailbox mb = new Mailbox("[email protected]"); 

FindFoldersResults findResults = service.FindFolders(
    WellKnownFolderName.Inbox, 
    new FolderView(int.MaxValue)); 

foreach (Folder folder in findResults.Folders) 
{ 
    Console.WriteLine(folder.DisplayName); 
} 

Questo in parte funziona perché restituisce le cartelle ABC, XYZ e 123; sfortunatamente, non restituisce le cartelle all'interno di ciascuna di queste cartelle (ABC 2, ABC 3, XYZ 2, 123 A, 123 B, 123 C).

Inoltre, è possibile che una cartella possa avere più di un livello di sottocartelle al suo interno.

Come posso scrivere questo codice in modo che restituisca tutte le sottocartelle indipendentemente da quanto profondamente annidate possano essere?

risposta

12

È possibile indicare a EWS di eseguire un deep traversal durante la ricerca nelle cartelle. È possibile farlo utilizzando la proprietà FolderView.Traversal. Il tuo codice sarebbe poi cambiato in qualcosa di simile al seguente:

FindFoldersResults findResults = service.FindFolders(
    WellKnownFolderName.Inbox, 
    new FolderView(int.MaxValue) { Traversal = FolderTraversal.Deep }); 
1

Si possono ricercare le vostre richieste e ottenere l'intera gerarchia delle cartelle dal server in appena un paio di telefonate. La chiave è la proprietà FolderView.Traversal, come indicato da Jacob.

Ad esempio, per una cassetta postale di Exchange con ~ 1.300 cartelle il codice riportato sotto fa solo 2 richieste. È possibile impostare le dimensioni della pagina in base alle proprie esigenze, purché si mantenga al di sotto o al di sotto del limite del server.

FYI: Exchange Online (Office365) limite massimo di 1.000 elementi in una risposta. Non ho provato, quindi non posso parlare per limiti simili quando si esegue una query su un server Exchange locale.

using Microsoft.VisualBasic; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using Exchange = Microsoft.Exchange.WebServices.Data; 

static internal class Main 
{ 
    public static void Main() 
    { 
    Exchange.ExchangeService oService = default(Exchange.ExchangeService); 
    Dictionary<string, User> oUsers = default(Dictionary<string, User>); 

    oUsers = new Dictionary<string, User>(); 
    oUsers.Add("User1", new User("[email protected]", "Some-Fancy-Password1")); 
    oUsers.Add("User2", new User("[email protected]", "Some-Fancy-Password2")); 

    oUsers.ToList.ForEach((KeyValuePair<string, User> Credential) => { File.Delete(LOG_FILE_PATH.ToFormat(Credential.Key)); }); 

    oUsers.ToList.ForEach((KeyValuePair<string, User> Credential) => 
    { 
     LogFileName = Credential.Key; 

     Console.WriteLine("Getting message counts for mailbox [{0}]...", LogFileName); 
     Console.WriteLine(); 

     oService = Service.ConnectToService(Credential.Value); 

     GetAllFolders(oService, LOG_FILE_PATH.ToFormat(Credential.Key)); 

     Console.Clear(); 
    }); 

    Console.WriteLine(); 
    Console.Write("Press any key to exit..."); 
    Console.ReadKey(); 
    } 

    private static void GetAllFolders(Exchange.ExchangeService Service, string LogFilePath) 
    { 
    Exchange.ExtendedPropertyDefinition oIsHidden = default(Exchange.ExtendedPropertyDefinition); 
    List<Exchange.Folder> oFolders = default(List<Exchange.Folder>); 
    Exchange.FindFoldersResults oResults = default(Exchange.FindFoldersResults); 
    bool lHasMore = false; 
    Exchange.Folder oChild = default(Exchange.Folder); 
    Exchange.FolderView oView = default(Exchange.FolderView); 

    short nPageSize = 0; 
    short nOffSet = 0; 

    List<string> oPaths = default(List<string>); 
    List<string> oPath = default(List<string>); 

    oIsHidden = new Exchange.ExtendedPropertyDefinition(0x10f4, Exchange.MapiPropertyType.Boolean); 
    nPageSize = 1000; 
    oFolders = new List<Exchange.Folder>(); 
    lHasMore = true; 
    nOffSet = 0; 

    while (lHasMore) { 
     oView = new Exchange.FolderView(nPageSize, nOffSet, Exchange.OffsetBasePoint.Beginning); 
     oView.PropertySet = new Exchange.PropertySet(Exchange.BasePropertySet.IdOnly); 
     oView.PropertySet.Add(oIsHidden); 
     oView.PropertySet.Add(Exchange.FolderSchema.ParentFolderId); 
     oView.PropertySet.Add(Exchange.FolderSchema.DisplayName); 
     oView.PropertySet.Add(Exchange.FolderSchema.FolderClass); 
     oView.PropertySet.Add(Exchange.FolderSchema.TotalCount); 
     oView.Traversal = Exchange.FolderTraversal.Deep; 

     oResults = Service.FindFolders(Exchange.WellKnownFolderName.MsgFolderRoot, oView); 
     oFolders.AddRange(oResults.Folders); 

     lHasMore = oResults.MoreAvailable; 

     if (lHasMore) { 
     nOffSet += nPageSize; 
     } 
    } 

    oFolders.RemoveAll(Folder => Folder.ExtendedProperties(0).Value == true); 
    oFolders.RemoveAll(Folder => Folder.FolderClass != "IPF.Note"); 

    oPaths = new List<string>(); 

    oFolders.ForEach(Folder => 
    { 
     oChild = Folder; 
     oPath = new List<string>(); 

     do { 
     oPath.Add(oChild.DisplayName); 
     oChild = oFolders.SingleOrDefault(Parent => Parent.Id.UniqueId == oChild.ParentFolderId.UniqueId); 
     } while (oChild != null); 

     oPath.Reverse(); 
     oPaths.Add("{0}{1}{2}".ToFormat(Strings.Join(oPath.ToArray, DELIMITER), Constants.vbTab, Folder.TotalCount)); 
    }); 

    oPaths.RemoveAll(Path => Path.StartsWith("Sync Issues")); 

    File.WriteAllText(LogFilePath, Strings.Join(oPaths.ToArray, Constants.vbCrLf)); 
    } 

    private static string LogFileName; 
    private const string LOG_FILE_PATH = "D:\\Emails\\Remote{0}.txt"; 
    private const string DELIMITER = "\\"; 
} 

internal class Service 
{ 
    public static Exchange.ExchangeService ConnectToService(User User) 
    { 
    return Service.ConnectToService(User, null); 
    } 

    public static Exchange.ExchangeService ConnectToService(User User, Exchange.ITraceListener Listener) 
    { 
    Exchange.ExchangeService oService = default(Exchange.ExchangeService); 

    oService = new Exchange.ExchangeService(Exchange.ExchangeVersion.Exchange2013_SP1); 
    oService.Credentials = new NetworkCredential(User.EmailAddress, User.Password); 
    oService.AutodiscoverUrl(User.EmailAddress, RedirectionUrlValidationCallback); 

    if (Listener != null) { 
     oService.TraceListener = Listener; 
     oService.TraceEnabled = true; 
     oService.TraceFlags = Exchange.TraceFlags.All; 
    } 

    return oService; 
    } 

    private static bool RedirectionUrlValidationCallback(string RedirectionUrl) 
    { 
    var _with1 = new Uri(RedirectionUrl); 
    return _with1.Scheme.ToLower == "https"; 
    } 
} 

internal class User 
{ 
    public User(string EmailAddress) 
    { 
    _EmailAddress = EmailAddress; 
    _Password = new SecureString(); 
    } 

    public User(string EmailAddress, string Password) 
    { 
    _EmailAddress = EmailAddress; 
    _Password = new SecureString(); 

    Password.ToList.ForEach((char Chr) => { this.Password.AppendChar(Chr); }); 

    Password.MakeReadOnly(); 
    } 

    public static User GetUser() 
    { 
    User functionReturnValue = null; 
    string sEmailAddress = null; 
    ConsoleKeyInfo oUserInput = default(ConsoleKeyInfo); 

    Console.Write("Enter email address: "); 
    sEmailAddress = Console.ReadLine; 
    Console.Write("Enter password: "); 

    functionReturnValue = new User(sEmailAddress); 

    while (true) { 
     oUserInput = Console.ReadKey(true); 

     if (oUserInput.Key == ConsoleKey.Enter) { 
     break; // TODO: might not be correct. Was : Exit While 

     } else if (oUserInput.Key == ConsoleKey.Escape) { 
     functionReturnValue.Password.Clear(); 

     } else if (oUserInput.Key == ConsoleKey.Backspace) { 
     if (functionReturnValue.Password.Length != 0) { 
      functionReturnValue.Password.RemoveAt(functionReturnValue.Password.Length - 1); 
     } 

     } else { 
     functionReturnValue.Password.AppendChar(oUserInput.KeyChar); 
     Console.Write("*"); 

     } 
    } 

    if (functionReturnValue.Password.Length == 0) { 
     functionReturnValue = null; 
    } else { 
     functionReturnValue.Password.MakeReadOnly(); 
     Console.WriteLine(); 
    } 
    return functionReturnValue; 
    } 

    public string EmailAddress { get; } 

    public SecureString Password { get; } 
} 

internal class TraceListener : Exchange.ITraceListener 
{ 

    public void Trace(string TraceType, string TraceMessage) 
    { 
    File.AppendAllText("{0}.txt".ToFormat(Path.Combine("D:\\Emails\\TraceOutput", Guid.NewGuid.ToString("D"))), TraceMessage); 
    } 
} 

//======================================================= 
//Service provided by Telerik (www.telerik.com) 
//Conversion powered by NRefactory. 
//Twitter: @telerik 
//Facebook: facebook.com/telerik 
//======================================================= 
+1

Voto downgot dato che si trattava di una domanda C#. – garfbradaz

+0

@garfbradaz: Apprezzo che tu lo dica. Non sono d'accordo sul fatto che valga la pena di procedere a una downvote: la traduzione è semplicemente semplice in questi giorni, ma questo è un altro punto. Quindi se modifico e traduco in C#, questo risolverà le cose nella tua vista? – InteXX

+2

@garfbradaz - Se traduco in C# e postare una modifica, si guadagnerà il voto? – InteXX

Problemi correlati