(WebAPI)OneNote API (C Sharp) を使いページ コンテンツを表示するサンプル コード

Last Update:

(※ 2017 年 2 月 17 日に Japan Office Developer Support Blog に公開した情報のアーカイブです。)

こんにちは、Office Developer サポートの森 健吾 (kenmori) です。

今回の投稿では、OneNote API を使用して、ノート、セクション、ページを選択し、コンテンツを表示するプログラムを、実際に C# で開発するエクスペリエンスをご紹介します。

ウォークスルーのような形式にしておりますので、慣れていない方も今回の投稿を一通り実施することで、プログラム開発を経験し理解できると思います。本投稿では、現実的な実装シナリオを重視するよりも、OneNote API を理解するためになるべくシンプルなコードにすることを心掛けています。例外処理なども含めていませんので、実際にコーディングする際には、あくまでこのコードを参考する形でご検討ください。

現在のところ Microsoft Graph において OneNote API はベータ版のみの提供となります。ベータ版の API は本番環境における使用はサポートされません。そのため、代わりに OneNote エンドポイント (https://www.onenote.com) 配下に要求を実行する実装コードで実現しております。

事前準備

以前の投稿をもとに、Azure AD にアプリケーションの登録を完了してください。少なくとも以下のデリゲートされたアクセス許可が必要です。

・View OneNote Notebooks

その上で、クライアント ID とリダイレクト URI を控えておいてください。

開発手順

1. Visual Studio を起動し、Windows フォーム アプリケーションを開始します。
2. ソリューション エクスプローラにて [参照] を右クリックし、[NuGet パッケージの管理] をクリックします。
3. ADAL で検索し、Microsoft.IdentityMode.Clients.ActiveDirectory をインストールします。
4. [OK] をクリックし、[同意する] をクリックします。
5. 次に同様の操作で Newtonsoft で検索し、Newtonsoft.Json をインストールします。
6. 次にフォームをデザインします。

コントロール一覧

  • OneNoteTestForm フォーム
  • NoteBooksCB コンボボックス
  • SectionsCB コンボ ボックス
  • PagesCB コンボボックス
  • ContentTC タブコントロール (TabPages : ブラウザー表示、HTML 表示)
  • ContentWB Web ブラウザー コントロール (ブラウザー表示のタブに配置)
  • ContentTB テキストエディタ (HTML 表示のタブに配置、MultiLine = True)

7. プロジェクトを右クリックし、[追加] – [新しい項目] をクリックします。
8. MyNotes.cs を追加します。
9. 以下のような定義 (JSON 変換用) を記載します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections.Generic;

namespace OneNoteDemo
{
public class NoteBooks
{
public List<NoteBook> Value { get; set; }
}
public class NoteBook
{
public string Name { get; set; }
public string SectionsUrl { get; set; }
}
public class Sections
{
public List<Section> Value { get; set; }
}
public class Section
{
public string Name { get; set; }
public string PagesUrl { get; set; }
}
public class Pages
{
public List<Page> Value { get; set; }
}
public class Page
{
public string Title { get; set; }
public string ContentUrl { get; set; }
}
}

10. フォームのコードに移動します。
11. using を追記しておきます。

1
2
3
4
5
6
7
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Windows.Forms;

12. フォームのメンバー変数に以下を加えます。
※ clientid や redirecturi は Azure AD で事前に登録したものを使用ください。

1
2
3
4
5
6
7
const string resource = "https://onenote.com/";
const string clientid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const string redirecturi = "urn:onenotedemo";
// ADFS 環境で SSO ドメイン以外のテナントのユーザーを試す場合はコメント解除
//const string loginname = "user@tenant.onmicrosoft.com";
string AccessToken;

13. フォームのデザインでフォームをダブルクリックし、ロード時のイベントを実装します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private async void OneNoteTestForm_Load(object sender, EventArgs e)
{
AccessToken = await GetAccessToken(resource, clientid, redirecturi);
DisplayNotes();
}

private async Task<string> GetAccessToken(string resource, string clientid, string redirecturi)
{
AuthenticationContext authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/common");
AuthenticationResult authenticationResult = await authenticationContext.AcquireTokenAsync(
resource,
clientid,
new Uri(redirecturi),
new PlatformParameters(PromptBehavior.Auto, null)
// ADFS 環境で SSO ドメイン以外のテナントのユーザーを試す場合はコメント解除
//, new UserIdentifier(loginname, UserIdentifierType.RequiredDisplayableId)
);
return authenticationResult.AccessToken;
}

private async void DisplayNotes()
{
// ノートブック取得 (REST)
string NoteBooksUrl = "https://www.onenote.com/api/v1.0/me/notes/notebooks/";
NoteBooks notebooks;
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get,
new Uri(NoteBooksUrl)
);
var response = await httpClient.SendAsync(request);
notebooks = JsonConvert.DeserializeObject<NoteBooks>(response.Content.ReadAsStringAsync().Result);
}
// ノートブック コンボボックスの描画
NotebooksCB.DataSource = notebooks.Value;
NotebooksCB.DisplayMember = "Name";
// 先頭アイテムを自動選択
if (NotebooksCB.Items.Count > 0)
{
NotebooksCB.SelectedIndex = 0;
}
}

14. NoteBooksCB の SelectedIndexChanged イベントをダブルクリックして、処理を実装します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private async void NotesCB_SelectedIndexChanged(object sender, EventArgs e)
{
// 選択したノートブックが保持するセクション一覧の URL を取得
string SectionsUrl = ((NoteBook)NotebooksCB.SelectedItem).SectionsUrl;
Sections sections;
if (!string.IsNullOrEmpty(SectionsUrl))
{
// セクション一覧を取得 (REST)
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get,
new Uri(SectionsUrl)
);
var response = await httpClient.SendAsync(request);
sections = JsonConvert.DeserializeObject<Sections>(response.Content.ReadAsStringAsync().Result);
}
// セクションをコンボボックスに描画
SectionsCB.DataSource = sections.Value;
SectionsCB.DisplayMember = "Name";
// 先頭アイテムを自動選択
if (SectionsCB.Items.Count > 0)
{
SectionsCB.SelectedIndex = 0;
}
}
}

15. SectionsCB の SelectedIndexChanged イベントをダブルクリックして、処理を実装します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private async void SectionsCB_SelectedIndexChanged(object sender, EventArgs e)
{
// 選択したセクションが保持するページ一覧の URL を取得
string PagesUrl = ((Section)SectionsCB.SelectedItem).PagesUrl;
Pages pages;
if (!string.IsNullOrEmpty(PagesUrl))
{
// ページ一覧を取得 (REST)
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get,
new Uri(PagesUrl)
);
var response = await httpClient.SendAsync(request);
pages = JsonConvert.DeserializeObject<Pages>(response.Content.ReadAsStringAsync().Result);
}
// ページをコンボボックスに描画
PagesCB.DataSource = pages.Value;
PagesCB.DisplayMember = "Title";
// 先頭アイテムを自動選択
if (PagesCB.Items.Count > 0)
{
PagesCB.SelectedIndex = 0;
}
}
}

16. PagesCBの SelectedIndexChanged イベントをダブルクリックして、処理を実装します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private async void PagesCB_SelectedIndexChanged(object sender, EventArgs e)
{
// 選択したページが保持するコンテンツの URL を取得
string ContentUrl = ((Page)PagesCB.SelectedItem).ContentUrl;
if (!string.IsNullOrEmpty(ContentUrl))
{
string content = "";
// ページ一覧を取得 (REST)
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get,
new Uri(ContentUrl)
);
var response = await httpClient.SendAsync(request);
content = response.Content.ReadAsStringAsync().Result;
}
// コンテンツをテキスト ボックスに描画
ContentTb.Text = content;
// コンテンツをブラウザー コントロールに描画
ContentWb.DocumentText = content;
}
}

上記ソリューションをビルドして、OneNote API の動作をご確認ください。

動作概要

・左上から最初のコンボボックスに自分の OneNote ノートブックが表示されます。
・左上から 2 番目のコンボボックス名には、選択したノートのセクションが表示されます。
・左上から 3 番目のコンボボックス名には、選択したセクション内のページが表示されます。
・画面下のタブ コントロール左のブラウザー表示では選択したページのコンテンツが表示され、HTML 表示ではページのソースが確認できます。

補足 : このコードでは、ページ コンテンツとして返された HTML をブラウザー コンポーネントで表示するだけとなります。アクセストークンを送信して、画像などのページ内に埋め込まれたリソース データを取得できないためリンク切れのような状態になります。

OneNote Online にもアクセスして内容と比較してみましょう。

参考情報

OneNote API についてさらに詳細な情報を確認する場合は、以下の情報をご参考にしてください。

タイトル : OneNote の開発
アドレス : https://msdn.microsoft.com/ja-jp/office/office365/howto/onenote-landing

タイトル : OneNote の認証とアクセス許可
アドレス : https://msdn.microsoft.com/ja-jp/office/office365/howto/onenote-auth

タイトル : OneNote authentication and Azure AD application permissions
アドレス : https://msdn.microsoft.com/en-us/office/office365/howto/onenote-auth-appperms

タイトル : OneNote API を使用して開発する
アドレス : https://msdn.microsoft.com/ja-jp/library/office/dn575421.aspx

タイトル : OneNote デベロッパーセンター
アドレス : http://dev.onenote.com/docs

今回の投稿は以上です。

本情報の内容 (添付文書、リンク先などを含む) は、作成日時点でのものであり、予告なく変更される場合があります。