(WebAPI)Microsoft Graph - OneDrive API (C Sharp) を使ったサンプル コード

Last Update:

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

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

今回の投稿では、Microsoft Graph – OneDrive API を実際に C# で開発するエクスペリエンスをご紹介します。

ウォークスルーのような形式にしておりますので、慣れていない方も今回の投稿を一通り実施することで、プログラム開発を経験し理解できると思います。本投稿では、現実的な実装シナリオを重視するよりも、OneDrive API を理解するためになるべくシンプルなコードにすることを心掛けています。

例外処理なども含めていませんので、実際にコーディングする際には、あくまでこのコードを参考する形でご検討ください。

事前準備

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

・Have full access to all files user can access
・Sign users in

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

開発手順

1. Visual Studio を起動し、Windows フォーム アプリケーションを開始します。
2. ソリューション エクスプローラにて [参照] を右クリックし、[NuGet パッケージの管理] をクリックします。

3. ADAL で検索し、Microsoft.IdentityMode.Clients.ActiveDirectory をインストールします。

4. [OK] をクリックし、[同意する] をクリックします。
5. 次に同様の操作で Newtonsoft で検索し、Newtonsoft.Json をインストールします。
6. 次にフォームをデザインします。

コントロール一覧

  • OneDriveTestForm フォーム
  • fileListLB リスト ボックス
  • fileNameTB テキスト ボックス
  • uploadBtn ボタン
  • renameBtn ボタン
  • deleteBtn ボタン
  • openFileDialog1 オープン ファイル ダイアログ

7. プロジェクトを右クリックし、[追加] – [新しい項目] をクリックします。
8. MyFile.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 Newtonsoft.Json;
using System.Collections.Generic;

namespace OneDriveDemo
{
public class MyFile
{
public string name { get; set; }
// 以下のプロパティは今回使用しませんが、デバッグ時に値を見ることをお勧めします。
public string webUrl { get; set; }
public string createdDateTime { get; set; }
public string lastModifiedDateTime { get; set; }
}

public class MyFiles
{
public List<MyFile> value;
}

// ファイル移動時に使います。
public class MyParentFolder
{
public string path { get; set; }
}

public class MyFileModify
{
public string name { get; set; }
// ファイル移動時に使います。
public MyParentFolder parentReference { get; set; }
}
}

補足
JSON 変換時にオブジェクト プロパティ側に別名を付けたい場合は、下記のように JsonProperty 属性を指定することで可能です。

1
2
[JsonProperty("name")]
public string FileName { get; set; }

10. フォームのコードに移動します。

11. using を追記しておきます。

1
2
3
4
5
6
7
8
9
10
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OneDriveDemo; //9. で作成した MyFile.cs 内の名前空間

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

1
2
3
4
5
6
7
const string resource = "https://graph.microsoft.com";
const string clientid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const string redirecturi = "urn:getaccesstokenfordebug";
// ADFS 環境で SSO ドメイン以外のテナントのユーザーを試す場合はコメント解除
// const string loginname = "admin@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
45
private async void Form1_Load(object sender, EventArgs e)
{
AccessToken = await GetAccessToken(resource, clientid, redirecturi);
DisplayFiles();
}

// アクセス トークン取得
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 DisplayFiles()
{
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get,
new Uri("https://graph.microsoft.com/v1.0/me/drive/root/children?$select=name,weburl,createdDateTime,lastModifiedDateTime")
);
var response = await httpClient.SendAsync(request);
MyFiles files = JsonConvert.DeserializeObject<MyFiles>(response.Content.ReadAsStringAsync().Result);

fileListLB.Items.Clear();
foreach (MyFile file in files.value)
{
fileListLB.Items.Add(file.name);
}
}
if (!string.IsNullOrEmpty(fileNameTB.Text))
{
fileListLB.SelectedItem = fileNameTB.Text;
}
}

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

1
2
3
4
5
// リスト ボックスで選択したファイルをテキスト ボックスに同期
private void fileListLB_SelectedIndexChanged(object sender, EventArgs e)
{
fileNameTB.Text = ((ListBox)sender).SelectedItem.ToString();
}

15. uploadBtn をダブルクリックして、ボタンクリックイベントを実装します。
※ この方式でアップロードできるファイル サイズには制限があります。

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
// ファイル アップロード処理
private async void uploadBtn_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
fileNameTB.Text = openFileDialog1.FileName.Substring(openFileDialog1.FileName.LastIndexOf("\\") + 1);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "octet-stream");
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Put,
new Uri(string.Format("https://graph.microsoft.com/v1.0/me/drive/root:/{0}:/content", fileNameTB.Text))
);
request.Content = new ByteArrayContent(ReadFileContent(openFileDialog1.FileName));
var response = await httpClient.SendAsync(request);
MessageBox.Show(response.StatusCode.ToString());
}
DisplayFiles();
}
}

// ローカル ファイルの読み取り処理
private byte[] ReadFileContent(string filePath)
{
using (FileStream inStrm = new FileStream(filePath, FileMode.Open))
{
byte[] buf = new byte[2048];
using (MemoryStream memoryStream = new MemoryStream())
{
int readBytes = inStrm.Read(buf, 0, buf.Length);
while (readBytes > 0)
{
memoryStream.Write(buf, 0, readBytes);
readBytes = inStrm.Read(buf, 0, buf.Length);
}
return memoryStream.ToArray();
}
}
}

16. renameBtn をダブルクリックして、クリックイベントを実装します。

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
// ファイル名の変更処理
private async void renameBtn_Click(object sender, EventArgs e)
{
foreach (string fileLeafRef in fileListLB.SelectedItems)
{
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");

HttpRequestMessage request = new HttpRequestMessage(
new HttpMethod("PATCH"),
new Uri(string.Format("https://graph.microsoft.com/v1.0/me/drive/root:/{0}", fileLeafRef))
);

MyFileModify filemod = new MyFileModify();
filemod.name = fileNameTB.Text;
request.Content = new StringContent(JsonConvert.SerializeObject(filemod), Encoding.UTF8, "application/json");

var response = await httpClient.SendAsync(request);
MessageBox.Show(response.StatusCode.ToString());
}
}
DisplayFiles();
}

17. deleteBtn をダブルクリックして、クリックイベントを実装します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ファイル削除処理
private async void deleteBtn_Click(object sender, EventArgs e)
{
foreach (string fileLeafRef in fileListLB.SelectedItems)
{
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);

HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Delete,
new Uri(string.Format("https://graph.microsoft.com/v1.0/me/drive/root:/{0}", fileLeafRef))
);
var response = await httpClient.SendAsync(request);
MessageBox.Show(response.StatusCode.ToString());
}
}
fileNameTB.Text = "";
DisplayFiles();
}

18. ソリューションをビルドして、動作を確認しましょう。

 最初にログイン画面が表示され、ログインしたユーザーでアクセス トークンを取得します。
※ ディレクトリ同期されたドメインでダイアログを表示すると、ユーザー名・パスワードの入力画面が表示されず、自動的にログインされる場合があります。

該当ユーザーの OneDrive for Business のルート ディレクトリのファイル一覧が表示されます。

該当フォルダーで、ファイルのアップロードや名前変更、削除などの操作をお試しください。

参考情報

以下は、Microsoft Graph における OneDrive API の参考サイトです。

タイトル : Microsoft Graph でのファイルの作業
アドレス : https://graph.microsoft.io/ja-jp/docs/api-reference/v1.0/resources/onedrive

OneDrive API のリファレンスについては、以下のページをご確認いただき、OneDrive APIが持つ様々なメソッドをお試しください。

タイトル : Develop with the OneDrive API
アドレス : https://dev.onedrive.com/README.htm#

現時点では、OneDrive API で実装できる範囲について、OneDrive コンシューマ版と OneDrive for Business には相違があります。詳細は以下をご確認ください。

タイトル : Release notes for using OneDrive API with OneDrive for Business and SharePoint
アドレス : https://dev.onedrive.com/sharepoint/release-notes.htm

以下は、OneDrive API を紹介した Channel9 の動画になります。

タイトル : Office Dev Show - Episode 38 - OneDrive APIs in the Microsoft Graph
アドレス : https://channel9.msdn.com/Shows/Office-Dev-Show/Office-Dev-Show-Episode-38-OneDrive-APIs-in-the-Microsoft-Graph

Json.NET に関するドキュメントは以下をご参考にしてください。

タイトル : Json.NET Documentation
アドレス : http://www.newtonsoft.com/json/help/html/Introduction.htm

タイトル : Serializing and Deserializing JSON
アドレス : http://www.newtonsoft.com/json/help/html/SerializingJSON.htm

別投稿に記載した通り、開発工数削減のため、アプリケーション開発前に Graph Explorer, Fiddler や Postman などを使用して、あらかじめ使用する REST を確立しておくことをお勧めします。デバッグ方法については、以下をご参考にしてください。

タイトル : [WebAPI]Microsoft Graph を使用した開発に便利なツール群
アドレス : https://officesupportjp.github.io/blog/(WebAPI)Microsoft Graph を使用した開発に便利なツール群/

今回の投稿は以上です。 

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