演習 - Microsoft Graph を ASP.NET MVC Web アプリに統合する

完了

この演習では、アプリケーションに Microsoft Graph を組み込みます。 このアプリケーションに、.NET 用 Microsoft Graph クライアント ライブラリ を使用して、Microsoft Graph を呼び出します。

Outlook からカレンダー イベントを取得する

まず、最後のモジュールで作成した GraphHelper クラスを拡張します。

次の using ステートメントを Helpers/GraphHelper.cs ファイルの先頭に追加します。

using graph_tutorial.TokenStorage;
using Microsoft.Identity.Client;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Claims;
using System.Web;

GraphHelper クラスに以下のコードを追加します。

// Load configuration settings from PrivateSettings.config
private static string appId = ConfigurationManager.AppSettings["ida:AppId"];
private static string appSecret = ConfigurationManager.AppSettings["ida:AppSecret"];
private static string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];
private static List<string> graphScopes =
    new List<string>(ConfigurationManager.AppSettings["ida:AppScopes"].Split(' '));

public static async Task<IEnumerable<Event>> GetEventsAsync()
{
    var graphClient = GetAuthenticatedClient();

    var events = await graphClient.Me.Events.Request()
        .Select("subject,organizer,start,end")
        .OrderBy("createdDateTime DESC")
        .GetAsync();

    return events.CurrentPage;
}

private static GraphServiceClient GetAuthenticatedClient()
{
    return new GraphServiceClient(
        new DelegateAuthenticationProvider(
            async (requestMessage) =>
            {
                var idClient = ConfidentialClientApplicationBuilder.Create(appId)
                    .WithRedirectUri(redirectUri)
                    .WithClientSecret(appSecret)
                    .Build();

                var tokenStore = new SessionTokenStore(idClient.UserTokenCache,
                        HttpContext.Current, ClaimsPrincipal.Current);

                var userUniqueId = tokenStore.GetUsersUniqueId(ClaimsPrincipal.Current);
                var account = await idClient.GetAccountAsync(userUniqueId);

                // By calling this here, the token can be refreshed
                // if it's expired right before the Graph call is made
                var result = await idClient.AcquireTokenSilent(graphScopes, account)
                    .ExecuteAsync();

                requestMessage.Headers.Authorization =
                    new AuthenticationHeaderValue("Bearer", result.AccessToken);
            }));
}

注:

このコードの実行内容を考えましょう。

  • GetAuthenticatedClient 関数は、AcquireTokenSilent を呼び出す認証プロバイダーを使用して GraphServiceClient を初期化します。
  • GetEventsAsync 関数で次の手順を実行します。
    • 呼び出される URL は /v1.0/me/events です。
    • Select 関数は、各イベントに返されるフィールドを、ビューで実際に使用されるフィールドだけに制限します。
    • OrderBy 関数は、作成された日時で結果を並べ替えます。最新のアイテムが最初に表示されます。

カレンダー ビュー用のコントローラーを作成します。 ソリューション エクスプローラーControllers フォルダーを右クリックし、[コントローラーの追加>]を選択します。[MVC 5 コントローラー ] - [空] を選択し、[追加] を選択します。 コントローラーの名前を CalendarController に指定し、[追加] を選択します。 新しいファイルのすべての内容を次のコードで置き換えます。

using graph_tutorial.Helpers;
using System;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace graph_tutorial.Controllers
{
    public class CalendarController : BaseController
    {
        // GET: Calendar
        [Authorize]
        public async Task<ActionResult> Index()
        {
            var events = await GraphHelper.GetEventsAsync();

            // Change start and end dates from UTC to local time
            foreach (var ev in events)
            {
                ev.Start.DateTime = DateTime.Parse(ev.Start.DateTime).ToLocalTime().ToString();
                ev.Start.TimeZone = TimeZoneInfo.Local.Id;
                ev.End.DateTime = DateTime.Parse(ev.End.DateTime).ToLocalTime().ToString();
                ev.End.TimeZone = TimeZoneInfo.Local.Id;
            }

            return Json(events, JsonRequestBehavior.AllowGet);
        }
    }
}

アプリを起動し、サインインして、ナビゲーション バーの [カレンダー] リンクをクリックします。 すべてが正常に機能していれば、ユーザーのカレンダーにイベントの JSON ダンプが表示されます。

結果の表示

結果を表示するとき、よりユーザー フレンドリなビューを追加できます。

ソリューション エクスプローラーで、[ビュー/予定表] フォルダーを右クリックし、[ビューの追加]>を選択します。[MVC 5 ビュー] を選択し、[追加] を選択します。 ビューにインデックスという名前を付け、[追加] を選択します。 新しいファイルのすべての内容を次のコードで置き換えます。

@model IEnumerable<Microsoft.Graph.Event>

@{
    ViewBag.Current = "Calendar";
}

<h1>Calendar</h1>
<table class="table">
    <thead>
        <tr>
            <th scope="col">Organizer</th>
            <th scope="col">Subject</th>
            <th scope="col">Start</th>
            <th scope="col">End</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.Organizer.EmailAddress.Name</td>
                <td>@item.Subject</td>
                <td>@Convert.ToDateTime(item.Start.DateTime).ToString("M/d/yy h:mm tt")</td>
                <td>@Convert.ToDateTime(item.End.DateTime).ToString("M/d/yy h:mm tt")</td>
            </tr>
        }
    </tbody>
</table>

これにより、イベントのコレクションがループされ、各イベントにテーブル行が追加されます。

Controllers/CalendarController.csIndex 関数から return Json(events, JsonRequestBehavior.AllowGet); 行を削除し、次のコードに置き換えます。

return View(events);

アプリを起動し、サインインして、[カレンダー] リンクをクリックします。 アプリにイベントの表が表示されます。

イベント表のスクリーンショット

要約

この演習では、アプリケーションに Microsoft Graph を組み込みます。 このアプリケーションに、.NET 用 Microsoft Graph クライアント ライブラリを使用して、Microsoft Graph を呼び出しました。

自分の知識をテストする

1.

MSAL SDK のオブジェクトのうち、対話ユーザーを持つ ASP.NET アプリケーション用に Microsoft ID からアクセス トークンを取得するのに最も適しているものはどれですか?

2.

Microsoft Graph SDK に含まれているオブジェクトのうち、Microsoft Graph に要求を送信するために使用されるのはどれですか?