【问题标题】:Using Microsoft.Graph to list calendars with C# Console Application使用 Microsoft.Graph 通过 C# 控制台应用程序列出日历
【发布时间】:2017-08-27 09:46:54
【问题描述】:

我在这里让自己陷入真正的泡菜。 :( 我只是不明白如何转移我在这里看到的内容:

https://developer.microsoft.com/en-us/graph/docs/api-reference/beta/api/user_list_calendars

进入我的 C# 控制台应用程序的上下文。

我做了这么多:

//Set the scope for API call to user.read
string[] _scopes = new string[] { "user.read",  "calendars.read" };

并确认当我登录时它确实要求访问用户日历。

但我不知道从这里去哪里。我在示例代码中有这个:

   private void DisplayBasicTokenInfo(AuthenticationResult authResult)
    {
        string strTokenInfoText = "";
        if (authResult != null)
        {
            strTokenInfoText += $"Name: {authResult.User.Name}" + Environment.NewLine;
            strTokenInfoText += $"Username: {authResult.User.DisplayableId}" + Environment.NewLine;
            strTokenInfoText += $"Token Expires: {authResult.ExpiresOn.ToLocalTime()}" + Environment.NewLine;
            strTokenInfoText += $"Access Token: {authResult.AccessToken}" + Environment.NewLine;
            Console.WriteLine(strTokenInfoText);
        }
    }

但显然我无法从那里获取日历列表。

我在这里问了一个类似的问题,但没有答案,但从那以后我取得了更大的进步:

Using Microsoft Outlook API with C# to list calendars and add events

更新

我这样调整我的方法:

public async Task AquireToken()
{
    AuthenticationResult authResult = null;

    try
    {
        if (authResult == null)
        {
            authResult = await Program.PublicClientApp.AcquireTokenSilentAsync(_scopes, Program.PublicClientApp.Users.FirstOrDefault());
        }
    }
    catch (MsalUiRequiredException ex)
    {
        // A MsalUiRequiredException happened on AcquireTokenSilentAsync. This indicates you need to call AcquireTokenAsync to acquire a token
        System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

        try
        {
            authResult = await Program.PublicClientApp.AcquireTokenAsync(_scopes);
        }
        catch (MsalException msalex)
        {
            strResultsText = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
        }
    }
    catch (Exception ex)
    {
        strResultsText = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
    }

    if (authResult != null)
    {
        strResultsText = await GetHttpContentWithToken(_graphAPIEndpoint, authResult.AccessToken);

        DisplayBasicTokenInfo(authResult);

        GraphServiceClient graphClient = new GraphServiceClient(
             new DelegateAuthenticationProvider(
                 (requestMessage) =>
                 {
                     // Append the access token to the request.
                     requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
                     return Task.FromResult(0);
                 }));

        SignOut();
        if (strResultsText != "")
            Console.WriteLine(strResultsText);
    }
}

如你所见,我添加了这段代码:

GraphServiceClient graphClient = new GraphServiceClient(
     new DelegateAuthenticationProvider(
         (requestMessage) =>
         {
             // Append the access token to the request.
             requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
             return Task.FromResult(0);
         }));

我在SignOut 上设置了一个断点,但无法让它工作。

我希望能够使用graphClient.me.Calendars

困惑。

更新

我试过看读我。也许我只是在错误的地方做事?但是当我设置断点时:

这不是我所期望的。

更新 2

我这样调整了我的代码:

   if (authResult != null)
    {
        strResultsText = await GetHttpContentWithToken(_graphAPIEndpoint, authResult.AccessToken);

        DisplayBasicTokenInfo(authResult);

        GraphServiceClient graphClient = new GraphServiceClient(
                 new DelegateAuthenticationProvider(
                     (requestMessage) =>
                     {
                         // Append the access token to the request.
                         requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authResult.AccessToken);
                         return Task.FromResult(0);
                     }));

        var calendars = await graphClient
                             .Me
                             .Calendars
                             .Request()
                             .GetAsync();
        Console.WriteLine(calendars.Count.ToString());
        List<Calendar> listCalendars = calendars.ToList();
        foreach(Calendar oCalendar in listCalendars)
        {
            Console.WriteLine(oCalendar.Name);
        }
        SignOut();
        if (strResultsText != "")
            Console.WriteLine(strResultsText);
    }

SignOut 上有一个断点,即使监视列表说什么都没有,在我的控制台窗口中我有:

所以看起来它工作正常。我想我可能只需要调整我的代码逻辑并获取AquireToken 方法来返回令牌并从那里获取它。明天我会玩更多。

更新 3

多亏了你们的 cmets,我才开始工作:

public async Task BuildCalendarsList()
{
    if (_AuthResult == null)
        return;

    try
    {
        GraphServiceClient graphClient = new GraphServiceClient(
                 new DelegateAuthenticationProvider(
                     (requestMessage) =>
                     {
                         // Append the access token to the request.
                         requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", _AuthResult.AccessToken);
                         return Task.FromResult(0);
                     }));

        var calendars = await graphClient
                             .Me
                             .Calendars
                             .Request()
                             .GetAsync();

        Console.WriteLine($"Number of calendars: {calendars.Count}");

        _ListCalendars = calendars.ToList();
    }
    catch(Exception ex)
    {
        _ListCalendars = null;
        Console.WriteLine($"Error BuildCalendarsList: {ex.Message}");
    }
}

public void DisplayCalendarsList()
{
    try
    {
        foreach (Calendar oCalendar in _ListCalendars)
        {
            string strCalendarInfo = $"Calendar Name: {oCalendar.Name}";
            strCalendarInfo += $" Calendar Id: {oCalendar.Id}";
            Console.WriteLine(strCalendarInfo);
        }
    }
    catch(Exception ex)
    {
        Console.WriteLine($"Error DisplayCalendarsList: {ex.Message}");
    }
 }

【问题讨论】:

  • 这里的所有代码都与身份验证有关,而不是与检索日历列表有关。您是否收到验证错误?
  • 我可以得到弹出屏幕并且用户接受。我可以显示用户令牌信息。但我不知道从那里去哪里。
  • 您需要调用 Graph API 来请求日历列表。您可以在developer.microsoft.com/en-us/graph 找到完整的文档
  • Graph 和 Auth 是两个不同的东西。 Auth 是关于获取一个令牌,然后将其提供给 Graph、Skype、Outlook 等 API。
  • 您是否遵循了这些自述文件说明:github.com/microsoftgraph/msgraph-sdk-dotnet?

标签: c# console-application microsoft-graph-api


【解决方案1】:

为了他人的利益,这就是我的工作方式:

public bool InitAuthenticatedClientAsync()
{
    bool bSuccess = true;

    _graphClient = new GraphServiceClient(
        new DelegateAuthenticationProvider(
            async (requestMessage) =>
            {
                try
                {
                    var accounts = await PublicClientApp.GetAccountsAsync();
                    // See: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/MSAL.NET-3-released#acquiring-a-token-also-got-simpler
                    _AuthResult = await PublicClientApp.AcquireTokenSilent(_Scopes, accounts.FirstOrDefault()).ExecuteAsync();
                }
                catch (MsalUiRequiredException ex)
                {
                    // A MsalUiRequiredException happened on AcquireTokenSilentAsync. This indicates you need to call AcquireTokenAsync to acquire a token
                    System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

                    try
                    {
                        // See: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/MSAL.NET-3-released#acquiring-a-token-also-got-simpler
                        _AuthResult = await PublicClientApp.AcquireTokenInteractive(_Scopes).ExecuteAsync();
                    }
                    catch (MsalException msalex)
                    {
                        SimpleLog.Log(msalex);
                        Console.WriteLine("GetAuthenticatedClientAsync: Acquire token error. See log.");
                        bSuccess = false;
                    }
                }
                catch (Exception ex)
                {
                    SimpleLog.Log(ex);
                    Console.WriteLine("GetAuthenticatedClientAsync: Acquire token silently error. See log.");
                    bSuccess = false;
                }

                if(bSuccess)
                {
                    // Append the access token to the request.
                    requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", _AuthResult.AccessToken);

                    // Get event times in the current time zone.
                    requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
                }
            }));

    return bSuccess;
}

public async Task<bool> BuildCalendarsList()
{
    bool bSuccess = true;

    if (_graphClient == null)
        return false;

    try
    {
        var calendars = await _graphClient
                             .Me
                             .Calendars
                             .Request()
                             .GetAsync();


        foreach (Calendar oCalendar in calendars)
        {
            _CalendarInfo.AddCalendarEntry(oCalendar.Name, oCalendar.Id);
        }

        bSuccess = SaveCalendarInfo();
    }
    catch (Exception ex)
    {
        SimpleLog.Log(ex);
        Console.WriteLine("BuildCalendarsList: See error log.");
        bSuccess = false;
    }

    return bSuccess;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    相关资源
    最近更新 更多