Exemplo: Aplicativo OData moderno de área de trabalho do Windows 8

 

Publicado: janeiro de 2017

Aplicável a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Este código de exemplo é para o Atualização do Microsoft Dynamics CRM 2015 e Microsoft Dynamics CRM Online 2015.Este código pode ser encontrado no seguinte local no pacote de download:

SampleCode\CS\ModernAndMobileApps\ModernOdataApp

Baixe o pacote do SDK do Microsoft Dynamics CRM.

Requisitos

Este exemplo requer os pacotes NuGet Microsoft.Preview.WindowsAzure.ActiveDirectory.Authentication e Microsoft.IdentityModel.Clients.ActiveDirectory. Esses pacotes são baixados e instalados automaticamente durante o carregamento da solução do projeto.

Para obter mais informações sobre os requisitos necessários à execução do código de exemplo fornecido neste SDK, consulte Usar o código de exemplo e auxiliar.

Demonstra

A tela principal do aplicativo de exemplo do Windows 8

Interface com o usuário fixada do aplicativo de exemplo

Esse exemplo mostra como gravar um aplicativo moderno de desktop Windows 8.1 que possa enviar solicitações para o serviço Web da organização sem se vincular aos assemblies do SDK. Esse exemplo usa o protocolo Biblioteca de Autenticação do Active Directory (ADAL) do Microsoft Azure e OData.

Quando há sete quadros exibidos na página principal do aplicativo, somente os quadros Contas e Tarefas são conectados ao código do manipulador de eventos. Os outros quadros são apenas espaços reservados.

O código de exemplo é configurado para uso com o servidor Microsoft Dynamics 365 (online) e uma organização fictícia, mas também pode ser usado com um servidor IFD.

Trechos de código que mostram somente as principais seções do exemplo completo são mostrados mais adiante neste tópico.

Exemplo

O trecho do código a seguir mostra como autenticar o usuário com o serviço Web da organização.


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;
            }
        }
    }
}

Para que esse código funcione, primeiro você deve registrar o aplicativo em um provedor de identidade suportado (AD FS ou Active Directory do Microsoft Azure). Em seguida, você deve definir os valores variáveis para _clientID e CrmServiceUrl no código. O valor da ID do cliente foi definido durante o registro do aplicativo.Para obter mais informações:Passo a passo: Registrar o aplicativo Dynamics 365 com Ative Directory

Exemplo

O trecho do código a seguir mostra como recuperar registros da entidade do serviço Web da organização usando o código de protocolo OData em uma solicitação HTTP. O token de acesso de autenticação é colocado no cabeçalho de autorização.


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;
        }
    }
}

Confira Também

Crie aplicativos móveis e modernos
Biblioteca de Autenticação do Azure (AAL) para o Windows Store: uma Análise Profunda
Protegendo um aplicativo do Windows Store e serviço Web REST usando o Azure AD
OData.org

Microsoft Dynamics 365

© 2017 Microsoft. Todos os direitos reservados. Direitos autorais