2011-09-28 39 views
7

Tôi có Inbox cấu trúc thư mục sau:Tìm tất cả các thư mục con của thư mục Inbox sử dụng EWS

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

Tôi đang sử dụng Exchange Web Services và mã sau đây để tìm các thư mục con của thư mục Inbox:

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

Điều này một phần hoạt động vì nó trả về các thư mục ABC, XYZ và 123; Thật không may, nó không trả lại các thư mục bên trong mỗi thư mục đó (ABC 2, ABC 3, XYZ 2, 123 A, 123 B, 123 C).

Ngoài ra, có thể thư mục có thể có nhiều cấp thư mục con trong đó.

Làm cách nào để tôi viết mã này để mã sẽ trả về tất cả các thư mục con bất kể chúng lồng nhau như thế nào?

Trả lời

12

Bạn có thể yêu cầu EWS thực hiện chuyển động sâu khi tìm kiếm các thư mục. Bạn có thể thực hiện việc này bằng cách sử dụng thuộc tính FolderView.Traversal. Mã của bạn sau đó sẽ được thay đổi thành một cái gì đó tương tự như sau:

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

Bạn có thể yêu cầu và nhận toàn bộ hệ thống phân cấp thư mục từ máy chủ chỉ trong một vài cuộc gọi. Điều quan trọng là tài sản FolderView.Traversal, như Jacob cho biết.

Ví dụ: đối với hộp thư Exchange có ~ 1,300 thư mục, mã bên dưới chỉ thực hiện 2 yêu cầu. Bạn có thể đặt kích thước trang của mình thành bất kỳ thứ gì bạn thích, miễn là bạn ở lại hoặc thấp hơn giới hạn máy chủ.

FYI: Exchange Online (Office365) giới hạn tối đa 1.000 mục trong phản hồi. Tôi chưa thử nghiệm, vì vậy tôi không thể nói cho bất kỳ giới hạn tương tự khi truy vấn một máy chủ Exchange tại chỗ.

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

Bị bỏ qua vì đây là câu hỏi C#. – garfbradaz

+0

@garfbradaz: Đánh giá cao bạn nói như vậy. Tôi không đồng ý rằng nó có giá trị một downvote-dịch là chết đơn giản những ngày này - nhưng đó là một điểm hoàn toàn. Vì vậy, nếu tôi chỉnh sửa và dịch sang C#, điều đó có khắc phục được sự cố trong chế độ xem của bạn không? – InteXX

+2

@garfbradaz - Nếu tôi dịch sang C# và đăng chỉnh sửa, điều đó có kiếm được phiếu bầu không? – InteXX

Các vấn đề liên quan