サンプル: Windows 8 デスクトップ modern OData アプリ

 

公開日: 2017年1月

対象: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online

このサンプル コードは、Microsoft Dynamics CRM 2015 および Microsoft Dynamics CRM Online 2015 更新プログラム 向けです。このコードは、ダウンロード パッケージの次の場所にあります。

SampleCode\CS\ModernAndMobileApps\ModernOdataApp

Microsoft Dynamics CRM SDK パッケージをダウンロードします。

要件

このサンプルには、Microsoft.Preview.WindowsAzure.ActiveDirectory.Authentication および Microsoft.IdentityModel.Clients.ActiveDirectory NuGet パッケージが必要です。 これらのパッケージは、プロジェクトのソリューションを読み込むときに自動的にダウンロードされてインストールされます。

この SDK で提供するサンプル コードを実行するために必要な要件については、「サンプルとヘルパー コードの使用」を参照してください。

使用例

Windows 8 サンプル アプリケーションのメイン画面

サンプル アプリのタイル ユーザー インターフェイス

このサンプルは、SDK アセンブリにリンクしなくても組織の Web サービスへ要求を送信できる、Windows 8.1 のデスクトップ モダン アプリケーションの作成方法を示します。 このサンプルでは、Microsoft Azure の Active Directory 認証ライブラリ (ADAL) と OData プロトコルを使用します。

7 つのタイルがメイン アプリケーション ページに表示される中で、取引先企業とタスクのタイルのみがイベント ハンドラー コードに接続されます。 残りのタイルは単なるプレースホルダーです。

コード例は Microsoft Dynamics 365 (オンライン) サーバーおよび架空の組織で使用するように構成されていますが、IFD サーバーでも使用できます。

完全なサンプルの主要なセクションだけを示したコード スニペットをこのトピックで後述します。

次のコード スニペットは、組織の Web サービスでユーザーを認証する方法を示しています。


using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Threading.Tasks;
using Windows.UI.Popups;
using Windows.Security.Authentication.Web;
using System.Net;
using System.Threading;
using System.IO;
using System.Text;

namespace ModernOdataApp
{
    /// <summary>
    /// Manages authentication with the organization web service.
    /// </summary>
    public static class CurrentEnvironment
    {
        # region Class Level Members

        private static AuthenticationContext _authenticationContext;

        // TODO Set these string values as approppriate for your app registration and organization.
        // For more information, see the SDK topic "Walkthrough: Register an app with Active Directory".
        private const string _clientID = "893262be-fbdc-4556-9325-9f863b69495b";
        public const string CrmServiceUrl = "https://my-domain.crm.dynamics.com/";

        # endregion

        // <summary>
        /// Perform any required app initialization.
        /// This is where authentication with Active Directory is performed.
        public static async Task<string> Initialize()
        {
            Uri serviceUrl = new System.Uri(CrmServiceUrl + "/XRMServices/2011/Organization.svc/web?SdkClientVersion=6.1.0000.0000");

            // Dyamics CRM Online OAuth URL.
            string _oauthUrl = DiscoveryAuthority(serviceUrl);

            // Obtain the redirect URL for the app. This is only needed for app registration.
            Uri redirectUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();

            // Obtain an authentication token to access the web service. 
            _authenticationContext = new AuthenticationContext(_oauthUrl, false);
            AuthenticationResult result = await _authenticationContext.AcquireTokenAsync(CrmServiceUrl, _clientID, redirectUri);

            // Verify that an access token was successfully acquired.
            if (result.Status != AuthenticationStatus.Success)
            {
                if (result.Error == "authentication_failed")
                {
                    // Try again.
                    _authenticationContext = new AuthenticationContext(_oauthUrl, false);
                    result = await _authenticationContext.AcquireTokenAsync(CrmServiceUrl, _clientID, redirectUri);
                }
                else
                {
                    DisplayErrorWhenAcquireTokenFails(result);
                }
            }
            return result.AccessToken;
        }

        /// <summary>
        /// Discover the authentication authority.
        /// </summary>
        /// <param name="serviceUrl">The URL of the organization's SOAP endpoint. </param>
        /// <returns>The authority URL.</returns>
        /// <remarks>The service URL must contain the SdkClient property.</remarks>
        /// <example>https://contoso.crm.dynamics.com/XRMServices/2011/Organization.svc/web?SdkClientVersion=6.1.0.533;</example>
        public static string DiscoveryAuthority(Uri serviceUrl)
        {
            // Use AuthenticationParameters to send a request to the organization's endpoint and
            // receive tenant information in the 401 challenge. 
            Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters parameters = null;
            HttpWebResponse response = null;
            try
            {
                // Create a web request where the authorization header contains the word "Bearer".
                HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);

                // The response is to be encoded.
                httpWebRequest.ContentType = "application/x-www-form-urlencoded";
                response = (HttpWebResponse)httpWebRequest.GetResponse();
            }

            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;

                // A 401 error should be returned. Extract any parameters from the response.
                // The response should contain an authorization_uri parameter.
                parameters = Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationParameters.
                    CreateFromResponseAuthenticateHeader((response.Headers)["WWW-Authenticate"]);
            }
            finally
            {
                if (response != null)
                    response.Dispose();
            }
            // Return the authority URL.
            return parameters.Authority;
        }

        /// <summary>
        /// Returns a response from an Internet resource. 
        /// </summary>       
        public static WebResponse GetResponse(this WebRequest request)
        {
            AutoResetEvent autoResetEvent = new AutoResetEvent(false);
            IAsyncResult asyncResult = request.BeginGetResponse(r => autoResetEvent.Set(), null);

            // Wait until the call is finished
            autoResetEvent.WaitOne(DefaultRequestTimeout);
            return request.EndGetResponse(asyncResult);
        }

        /// <summary>
        /// Get the DefaultRequestTimeout from the server.
        /// </summary>
        public static TimeSpan DefaultRequestTimeout { get; set; }

        /// <summary>
        /// Display an error message to the user.
        /// </summary>
        /// <param name="result">The authentication result returned from AcquireTokenAsync().</param>
        private static async void DisplayErrorWhenAcquireTokenFails(AuthenticationResult result)
        {
            MessageDialog dialog;

            switch (result.Error)
            {
                case "authentication_canceled":
                    // User cancelled, so no need to display a message.
                    break;
                case "temporarily_unavailable":
                case "server_error":
                    dialog = new MessageDialog("Please retry the operation. If the error continues, please contact your administrator.",
                        "Sorry, an error has occurred.");
                    await dialog.ShowAsync();
                    break;
                default:
                    // An error occurred when acquiring a token so show the error description in a MessageDialog.
                    dialog = new MessageDialog(string.Format(
                        "If the error continues, please contact your administrator.\n\nError: {0}\n\nError Description:\n\n{1}",
                        result.Error, result.ErrorDescription), "Sorry, an error has occurred.");
                    await dialog.ShowAsync();
                    break;
            }
        }
    }
}

このコードが機能するには、最初に、サポートされる ID プロバイダー (AD FS または Microsoft Azure Active Directory) でアプリケーションを登録する必要があります。 次に、コード内の _clientID と CrmServiceUrl の変数値を設定する必要があります。 クライアント ID の値はアプリケーション登録時に定義されました。詳細:チュートリアル: Active Directory に Dynamics 365 アプリを登録する

次のコード スニペットは、HTTP 要求で OData プロトコル コードを使用して、組織の Web サービスからエンティティ レコードを取得する方法を示しています。 認証アクセス トークンは認証ヘッダーに配置されます。


using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ModernOdataApp
{
    public static class HttpRequestBuilder
    {
        /// <summary>
        /// Retrieve entity record data from the organization web service. 
        /// </summary>
        /// <param name="accessToken">The web service authentication access token.</param>
        /// <param name="Columns">The entity attributes to retrieve.</param>
        /// <param name="entity">The target entity for which the data should be retreived.</param>
        /// <returns>Response from the web service.</returns>
        /// <remarks>Builds an OData HTTP request using passed parameters and sends the request to the server.</remarks>
        public static async Task<string> Retrieve(string accessToken, string[] Columns, string entity)
        {
            // Build a list of entity attributes to retrieve as a string.
            string columnsSet = "";
            foreach (string Column in Columns)
            {
                columnsSet += "," + Column;
            }

            // The URL for the OData organization web service.
            string url = CurrentEnvironment.CrmServiceUrl + "/XRMServices/2011/OrganizationData.svc/" + entity + "?$select=" + columnsSet.Remove(0, 1) + "";

            // Build and send the HTTP request.
            HttpClient httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, url);
            req.Method = HttpMethod.Get;

            // Wait for the web service response.
            HttpResponseMessage response;
            response = await httpClient.SendAsync(req);
            var responseBodyAsText = await response.Content.ReadAsStringAsync();

            return responseBodyAsText;
        }
    }
}

関連項目

モバイル アプリやモダン アプリを作成する
Windows ストアの Azure 認証ライブラリ (AAL): 掘り下げた分析
Azure AD を使用した Windows ストア アプリケーションと REST Web サービスの保護
OData.org

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. 著作権