C# 从所有Outlook联系人文件夹中获取联系人Microsoft Graph

C# 从所有Outlook联系人文件夹中获取联系人Microsoft Graph,c#,microsoft-graph-api,C#,Microsoft Graph Api,我正在使用Microsoft Graph检索联系人文件夹,代码如下: GraphServiceClient client = new GraphServiceClient(new DelegateAuthenticationProvider( (requestMessage) => { requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", a

我正在使用Microsoft Graph检索联系人文件夹,代码如下:

GraphServiceClient client = new GraphServiceClient(new DelegateAuthenticationProvider(
    (requestMessage) => {
        requestMessage.Headers.Authorization = 
          new AuthenticationHeaderValue("Bearer", accessToken);
        return Task.FromResult(0);
    }));

var contactsData = await client
    .Me
    .Contacts
    .Request()
    .Top(1000)
    .GetAsync();
"GraphScopes": "User.Read User.ReadBasic.All Mail.Send MailBoxSettings.ReadWrite Contacts.ReadWrite"
上述代码返回联系人,但仅返回默认文件夹中的联系人。我想从用户的所有文件夹中检索联系人

我尝试先获取文件夹,然后获取其联系人,但它会返回一个
Null引用异常
,因为联系人是
Null

var Folders = client
    .Me
    .ContactFolders
    .Request()
    .Top(1000)
    .GetAsync();

Folders.Wait();
var contacts = Folders.Result.SelectMany(a => a.Contacts).ToList();

我现在在这台机器上没有要测试的环境,但据我所知,您可以使用option query参数筛选子文件夹中的联系人

  • 你需要找出所有的子文件夹

    获取/users/{id | userPrincipalName}/contactFolders

  • 收集所有子文件夹Id
  • 在每个子文件夹中查找联系人

    获取/me/contactFolder/{id}/childFolders/{id}/contacts

  • 有关更多联系人文件夹和联系人相关信息。请阅读这些文件。

    首先,此示例代码是在.net core中创建的,您应该通过以下代码在配置中设置图形范围:

    GraphServiceClient client = new GraphServiceClient(new DelegateAuthenticationProvider(
        (requestMessage) => {
            requestMessage.Headers.Authorization = 
              new AuthenticationHeaderValue("Bearer", accessToken);
            return Task.FromResult(0);
        }));
    
    var contactsData = await client
        .Me
        .Contacts
        .Request()
        .Top(1000)
        .GetAsync();
    
    "GraphScopes": "User.Read User.ReadBasic.All Mail.Send MailBoxSettings.ReadWrite Contacts.ReadWrite"
    
    还请注意,ContactFolders仅在有多个文件夹时返回结果。默认联系人文件夹永远不会返回。如果用户没有其他文件夹,则返回空结果。如果要获取主文件夹和其他文件夹,则需要分别获取它们,然后合并结果

    // Get the defaultContacts
    var defaultContacts = await graphClient
        .Me
        .Contacts
        .Request()
        .GetAsync();
    
    // Get the contactFolders
    var contactFolders = await graphClient
        .Me
        .ContactFolders
        .Request()
        .GetAsync();
    
    // Use this to store the contact from all contact folder.
    List<Contact> contactFolderContacts = new List<Contact>();
    
    if (contactFolders.Count > 0) {
        for (int i = 0; i < contactFolders.Count; i++) {
            var folderContacts = await graphClient
                .Me
                .ContactFolders[contactFolders[i].Id]
                .Contacts
                .Request()
                .GetAsync();
    
            contactFolderContacts.AddRange(folderContacts.AsEnumerable());
        }
    
        // This will combine the contact from main folder and the additional folders.
        contactFolderContacts.AddRange(defaultContacts.AsEnumerable());
    } else {
        // This user only has the default contacts folder
        contactFolderContacts.AddRange(defaultContacts.AsEnumerable());
    }
    
    // Use this to test the result.
    foreach (var item in contactFolderContacts) {
        Debug.WriteLine("first:" + item.EmailAddresses);
    }
    
    //获取默认联系人
    var defaultContacts=等待图形客户端
    我
    .联系人
    .Request()
    .GetAsync();
    //获取联系人文件夹
    var contactFolders=等待图形客户端
    我
    .联系人文件夹
    .Request()
    .GetAsync();
    //使用此选项可存储“所有联系人”文件夹中的联系人。
    List contactFolderContacts=新列表();
    如果(contactFolders.Count>0){
    对于(int i=0;i
    @downvoter为什么选择downvote?如果您对该问题有具体问题,请务必在评论中告诉我,以便我可以根据Fetching
    ContactFolders
    修改该问题。Fetching只返回文件夹,而不返回其中的联系人。您需要为每个文件夹分别请求
    .Contacts
    ,以检索实际联系人。您的代码看起来不错,但我确实不理解您建议这些范围的原因。首先,我不确定它们会去哪里(什么“项目”?),但更重要的是,这唯一需要的范围是
    联系人。阅读
    (不包括在您建议的范围内)。@marclafler确定这些图形范围是.net核心项目配置。@marclafler这是一个net核心项目。我使用Contacts.ReadWrite替换Contacts.Read。最终用户可以根据他们的要求更改图形范围。我将对此进行测试并让您知道。我通过发出一个api调用来获取文件夹,然后通过另一个api调用传递文件夹id来检索联系人,从而解决了这个问题。我也会发布我的解决方案,并测试您的答案,如果这也有效的话,我会将其标记为答案。“我通过调用api来获取文件夹,然后通过另一个api调用传递文件夹id来检索联系人,从而解决了这个问题。”您的想法与我提供的代码类似,但我为扩展添加了一些额外的代码。