【转】Microsoft Graph 桌面应用程序
桌面應用程序,在我這篇文章的語境中,我是特指在Windows桌面上面直接運行的.NET應用程序,包括Console Application,WPF Application,Windows Forms Application, UWP Application,并且限于篇幅,我只會以Console Application作為演示,因為無論表現形式如何不同,它們從本質上是類似的。
本文所附帶示例代碼可以通過https://github.com/chenxizhang/office365dev/tree/master/samples/graph-consoleapplicationsample?訪問,這是由Visual Studio 2017編寫,開發語言為C#,在Windows 10 Enterprise上面測試通過。請注意,作為演示目的,我盡可能在范例代碼中僅包含最必要的代碼。
注冊Microsoft Graph應用程序
要進行具體的編程之前,你需要注冊Microsfot Graph應用程序。本系列文章約定,針對國際版我將采用Azure AD 2.0這種方式進行注冊,而針對中國版將采用Azure AD 1.0這種方式。這兩種方式的詳細操作步驟,以及我注冊好的范例應用程序,請參考
注冊Azure AD 2.0 應用程序
注冊中國版Microsoft Graph應用程序
創建Console Application
不要問我怎么做這個事情,你應該知道的。?
考慮安全認證功能
關鍵是,接下來你該如何考慮呢?有的人會聯想到OAuth,這是一個很好的想法。我在此前已經提到過如何分三個步驟實現Microsoft Graph應用開發,第一步是注冊應用程序,第二步是實現身份認證,第三步就是該怎么調用你就怎么調用。
下圖介紹了在Azure AD 2.0中支持的OAuth認證流程?
簡單地說,OAuth認證一般會有三個步驟
你當然可以在了解上述原理馬上開始編寫代碼,但這里要請你了解,為了降低開發人員在這塊的工作量,并且盡量進行標準化,Microsoft Graph針對不同的平臺和語言都有對應的SDK。請參考?https://developer.microsoft.com/zh-cn/graph/docs/get-started/get-started
具體到我們本篇文章的目標,如果Office 365是國際版,你可以使用Microsoft Graph Client Library?https://www.nuget.org/packages/Microsoft.Graph/??和 Microsoft Authentication Library?https://www.nuget.org/packages/Microsoft.Identity.Client/1.0.304142221-alpha
目前這個 Microsoft Authentication Library 的狀態是Preview,但是很值得期待,因為它還有針對.NET Core的版本
而如果是用中國版,你也可以使用 Active Directory Authentication Library .NET?https://msdn.microsoft.com/library/en-us/Mt417579.aspx?
實現國際版Microsoft Graph調用
首先,運行下面的命令安裝上面提到的兩個Library,并且進行更新
Install-Package Microsoft.Graph Install-Package Microsoft.Identity.Client -IncludePrereleaseUpdate-Package接下來,我們需要編寫一個方法,封裝一下Graph Authentication這個步驟.
備注,我認為這里還有可以改進的空間,最好是連這一步都可以省略掉。產品組是還沒有完全想好,日后應該會加上這塊實現。
class GraphAuthenticator : IAuthenticationProvider {static string token;static DateTimeOffset Expiration;public async Task AuthenticateRequestAsync(HttpRequestMessage request){string clientID = "45aa2ecc-5e57-4c91-86c1-b93064800c39";//這個ID是我創建的一個臨時App的ID,請替換為自己的string[] scopes = { "user.read", "mail.read", "mail.send"};var app = new PublicClientApplication(clientID);AuthenticationResult result = null;try{result = await app.AcquireTokenSilentAsync(scopes);token = result.Token;}catch (Exception){if (string.IsNullOrEmpty(token) || Expiration <= DateTimeOffset.UtcNow.AddMinutes(5)){result = await app.AcquireTokenAsync(scopes);Expiration = result.ExpiresOn;token = result.Token;}}request.Headers.Add("Authorization", $"Bearer {token}");} }有了這個類,接下來我們要調用Microsoft Graph簡直可以說是易如反掌,請參考下面的代碼
var client = new GraphServiceClient(new GraphAuthenticator());//創建客戶端代理 var user = client.Me.Request().GetAsync().Result;//獲取當前用戶信息 Console.WriteLine(user.DisplayName);var messages = client.Me.Messages.Request().GetAsync().Result;//獲取用戶的前十封郵件 foreach (var item in messages) {Console.WriteLine(item.Subject); }client.Me.SendMail(new Message() //發送郵件 {Subject = "調用Microsoft Graph發出的郵件",Body = new ItemBody(){ContentType = BodyType.Text,Content = "這是一封調用了Microsoft Graph服務發出的郵件,范例參考 https://github.com/chenxizhang/office365dev"},ToRecipients = new[]{new Recipient(){EmailAddress = new EmailAddress(){ Address ="ares@office365devlabs.onmicrosoft.com"}}} }, true).Request().PostAsync();Console.Read();完整代碼,請參考?https://github.com/chenxizhang/office365dev/blob/master/samples/graph-consoleapplicationsample/graph-consoleapplicationsample/Program.cs
就是這么簡單,就是這么任性,你可以馬上運行這個應用程序看看效果了?
輸入你的Office 365賬號和密碼(請注意,需要是國際版),然后點擊“Sign In”,Microsoft Graph將引導你進行授權確認?
不出意外的話,你現在就可以在控制臺窗口中看到當前登錄的用戶信息,十個郵件標題等信息了。
VB.NET 開發人員看過來
我不止一次聽到開發人員反饋說,現在在網絡上想一些VB或者VB.NET的代碼范例比較難。這是一個事實,我自己對VB是有感情的,為了向這部分開發人員致意,我特別提供了一個VB.NET的版本。
我不能擔保后續每一篇,每個范例都會提供VB.NET的版本,因為精力真的很有限。如果你有興趣根據我的C#的范例轉換為VB.NET代碼,歡迎跟我聯系。
Imports System.Net.Http Imports Microsoft.Graph Imports Microsoft.Identity.Client ''' <summary> ''' 這個是國際版Microsoft Graph的客戶端應用程序范例 ''' 作者:陳希章 ''' 時間:2017年3月23日 ''' </summary> Module Module1Sub Main()Dim serviceClient = New GraphServiceClient(New GraphAuthenticator())Dim user = serviceClient.Me.Request.GetAsync().Result'獲取用戶基本信息Console.WriteLine(user.DisplayName)Console.WriteLine(user.Mail)'獲取用戶的郵件列表Dim messages = serviceClient.Me.MailFolders.Inbox.Messages.Request.GetAsync().ResultFor Each item In messagesConsole.WriteLine(item.Subject)Next'發送郵件serviceClient.Me.SendMail(New Message() With {.Subject = "調用Microsoft Graph發出的郵件(VB.NET)",.Body = New ItemBody() With {.Content = "這是一封調用了Microsoft Graph服務發出的郵件,范例參考 https://github.com/chenxizhang/office365dev",.ContentType = BodyType.Text},.ToRecipients = New List(Of Recipient) From {New Recipient() With {.EmailAddress = New EmailAddress() With {.Address = "ares@office365devlabs.onmicrosoft.com"}}}}, True).Request.PostAsync()Console.Read()End SubPublic Class GraphAuthenticatorImplements IAuthenticationProviderShared token As StringShared Expiration As DateTimeOffsetPublic Async Function AuthenticateRequestAsync(request As HttpRequestMessage) As Task Implements IAuthenticationProvider.AuthenticateRequestAsyncDim clientID As String = "45aa2ecc-5e57-4c91-86c1-b93064800c39" '這個ID是我創建的一個臨時App的ID,請替換為自己的Dim scopes As String() = {"user.read", "mail.read", "mail.send"}Dim app As PublicClientApplication = New PublicClientApplication(clientID)Dim result As AuthenticationResultTryresult = Await app.AcquireTokenSilentAsync(scopes)token = result.TokenCatch ex As ExceptionIf (String.IsNullOrEmpty(token) OrElse Expiration <= DateTimeOffset.UtcNow.AddMinutes(5)) Thenresult = app.AcquireTokenAsync(scopes).ResultExpiration = result.ExpiresOntoken = result.TokenEnd IfEnd Tryrequest.Headers.Add("Authorization", $"Bearer {token}")End FunctionEnd ClassEnd Module實現中國版Microsoft Graph調用
接下來我們該看看在中國版Microsoft Graph調用方面有什么不同。雖然因為沒有封裝好的Microsoft Graph Client,但是看起來基本代碼也還算簡單易懂,請參考。
安裝下面這個Package
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory Update-Package編寫一個自定義方法獲取用戶的訪問令牌
static async Task<string> GetAccessToken() {var appId = "9c7dd51c-072c-4aea-aaee-fc57efacb150";var authorizationEndpoint = "https://login.chinacloudapi.cn/common/oauth2/authorize";//國際版是https://login.microsoftonline.com/common/oauth2/authorizevar resource = "https://microsoftgraph.chinacloudapi.cn"; //國際版是https://graph.microsoft.com var redirectUri = "http://nativeapplication";//其實這個應該去掉,目前必須要填,而且要跟注冊時一樣AuthenticationResult result = null;var context = new AuthenticationContext(authorizationEndpoint);result = await context.AcquireTokenAsync(resource, appId, new Uri(redirectUri), new PlatformParameters(PromptBehavior.Always));return result.AccessToken; }編寫一個自定義方法發起Microsoft Graph請求
/// <summary> /// 定義這個方法用來進行Rest調用 /// </summary> /// <param name="url"></param> /// <param name="token"></param> /// <returns></returns> static async Task<string> InvokeRestReqeust(string url, string token) {var client = new System.Net.WebClient();client.Headers.Add("Authorization", $"Bearer {token}");var result = await client.DownloadStringTaskAsync(url);return result;//請注意,這里直接返回字符串型的結果,它是Json格式的,有興趣的可以繼續在這個基礎上進行處理 }萬事俱備,下面就可以在主程序中組合使用這兩個方法進行Microsoft Graph調用了
static void Main(string[] args) {///獲得用戶的令牌var token = GetAccessToken().Result;//獲得用戶的基本信息var me = InvokeRestReqeust("https://microsoftgraph.chinacloudapi.cn/v1.0/me", token).Result;Console.WriteLine(me);//獲得用戶的郵件列表(前十封)var messages = InvokeRestReqeust("https://microsoftgraph.chinacloudapi.cn/v1.0/me/messages", token).Result;Console.WriteLine(messages);Console.Read();}VB.NET用戶看過來
我同樣為這個范例準備了一個VB.NET的版本,請大家參考
Imports System.Net Imports Microsoft.IdentityModel.Clients.ActiveDirectoryModule Module1Sub Main()'獲得用戶令牌Dim token = GetAccessToken().Result'獲得當前用戶基本信息Dim user = InvokeRestRequest("https://microsoftgraph.chinacloudapi.cn/v1.0/me", token).ResultConsole.WriteLine(user)'獲得用戶的郵件列表(前十封)Dim messages = InvokeRestRequest("https://microsoftgraph.chinacloudapi.cn/v1.0/me/messages", token).ResultConsole.WriteLine(messages)Console.Read()End SubAsync Function InvokeRestRequest(url As String, token As String) As Task(Of String)Dim client = New WebClient()client.Headers.Add("Authorization", $"Bearer {token}")Dim result = Await client.DownloadStringTaskAsync(url)Return result'請注意,這里直接返回字符串型的結果,它是Json格式的,有興趣的可以繼續在這個基礎上進行處理End FunctionAsync Function GetAccessToken() As Task(Of String)Dim appId = "9c7dd51c-072c-4aea-aaee-fc57efacb150"Dim authorizationEndpoint = "https://login.chinacloudapi.cn/common/oauth2/authorize"'國際版是https://login.microsoftonline.com/common/oauth2/authorizeDim resource = "https://microsoftgraph.chinacloudapi.cn" '國際版是https://graph.microsoft.comDim redirectUri = "http://nativeapplication" '其實這個應該去掉,目前必須要填,而且要跟注冊時一樣Dim result As AuthenticationResultDim context = New AuthenticationContext(authorizationEndpoint)result = Await context.AcquireTokenAsync(resource, appId, New Uri(redirectUri), New PlatformParameters(PromptBehavior.Auto))Return result.AccessTokenEnd FunctionEnd Module從上面的代碼對照來看,Azure AD 1.0的方式,需要開發人員處理更多細節,例如身份驗證,服務調用結果處理等等。如果有興趣并且有能力的朋友,歡迎在這個基礎上做一定的封裝,簡化開發。
本文所有代碼范例,可以通過?https://github.com/chenxizhang/office365dev/tree/master/samples/graph-consoleapplicationsample?查看或者下載?
結語
本文完整地介紹了針對國際版和中國版Office 365,在桌面應用程序中如何實現Microsoft Graph的集成。針對國際版,我采用的是Azure AD 2.0的方式;針對中國版,我采用的是Azure AD 1.0的方式。同時,為了照顧到VB.NET的開發人員,本文所有范例都提供了VB.NET的版本。
總結
以上是生活随笔為你收集整理的【转】Microsoft Graph 桌面应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比亚迪、长征之后 又一车企汉马科技宣布专
- 下一篇: 【转】Microsoft Graph 概