Compartir por


Tutorial: crear una aplicación ASP.NET Core Blazor WebAssembly mediante Microsoft Dataverse

Siga los pasos de este tutorial para crear una aplicación Blazor WebAssembly que se conecte al Dataverse. El objetivo de este artículo es comprender los pasos necesarios para autenticar a un usuario con una instancia de Dataverse específica y recuperar datos.

Blazor WebAssembly es uno de los dos modelos de alojamiento disponibles para ASP.NET Core Blazor. El otro es Blazor Server. Para obtener una descripción completa de las diferencias, vea Modelos de hospedaje ASP.NET Core Blazor.

Este tutorial depende de las instrucciones del artículo Proteger una aplicación independiente ASP.NET Core Blazor WebAssembly con Microsoft Entra ID. Porque Dataverse usa Microsoft Entra ID para la autenticación, este tutorial describirá cómo modificar la aplicación básica creada con la plantilla de aplicación proporcionada para que pueda conectarse a Dataverse.

Goal

Cuando complete este tutorial, tiene una aplicación Blazor WebAssembly que muestra datos de la tabla de cuentas de Dataverse a la que tiene acceso el usuario autenticado.

Representa el objetivo de este tutorial.

Requisitos previos

Para completar este tutorial, debe tener:

  • Acceso a un entorno de Dataverse con una base de datos
  • Un usuario de Dataverse con un rol de seguridad que proporciona acceso de lectura a las tablas Cuenta y Contacto
  • Conocimientos del lenguaje de programación C#
  • Tener conocimientos de ASP.NET Core Blazor es útil, pero no obligatorio
  • La última versión de Visual Studio 2022 con la carga de trabajo ASP.NET y desarrollo web instalada.

Paso 1: verificar los requisitos previos y la información sobre la base de datos

Asegurémonos de que su entorno esté configurado correctamente y de que comprenda dónde realizar las acciones del paso 2.

Verificar la base de datos de Dataverse

  1. Inicie sesión en Power Apps.

  2. Seleccione Soluciones en el panel de navegación.

    El portal de creadores que muestra un entorno sin una base de datos de Dataverse.

  3. Si no ve una lista de soluciones instaladas, use el selector de entorno en la parte superior para elegir un entorno diferente que tenga una base de datos. De lo contrario, cree nuevo entorno.

Obtenga el URI de la API web de Dataverse

Necesita la URL raíz del servicio de API web de la instancia. Esta URL se encuentra en la página de Recursos para desarrolladores de su entorno de Dataverse.

Siga las instrucciones que se encuentran en Ver o descargar recursos para desarrolladores para copiar la URL.

Se parece a esta: https://yourorgname.api.crm.dynamics.com/api/data/v9.2/

  1. Inicie sesión en Power Apps.

  2. Seleccione el icono de "gofre" en la esquina superior izquierda, y seleccione Administrador.

    Navegar al centro de administración de Microsoft 365.

  3. En la navegación izquierda del centro de administración de Microsoft 365, seleccione Mostrar todo y seleccione Identidad.

    Navegar al centro de administración de Microsoft Entra.

  4. En el centro de administración de Microsoft Entra, expanda el nodo Aplicaciones en el panel de navegación izquierdo y seleccione Registros de aplicaciones.

    Navegar a la página Microsoft Entra Registros de aplicaciones.

Aquí es donde comenzarás el paso 2.

Paso 2: crear una aplicación independiente Blazor WebAssembly usando Microsoft Entra ID para la autenticación

En el artículo Proteger una aplicación independiente ASP.NET Core Blazor WebAssembly con Microsoft Entra ID se proporciona un conjunto completo de instrucciones para crear la aplicación.

Estos pasos describirán cómo crear un registro de aplicación en Microsoft Entra ID y ejecutar un comando CLLI de .NET Core para generar el andamio para la aplicación básica con soporte para la autenticación de Microsoft Entra ID.

Nota

Estas instrucciones usan el comando CLI de .NET Core para generar la aplicación. Hay una plantilla de proyecto de Visual Studio para crear una aplicación Blazor WebAssembly, pero este tutorial no se ha verificado utilizando esa plantilla.

Vaya a Proteger una aplicación independiente ASP.NET Core Blazor WebAssembly con Microsoft Entra ID y siga las instrucciones para generar el proyecto básico de la aplicación.

Verificar que la aplicación funciona

Después de completar los pasos en Proteger una ASP.NET aplicación independiente Core Blazor WebAssembly con Microsoft Entra ID, debería poder presionar F5 en Visual Studio para ejecutar la aplicación.

Comportamiento predeterminado de la aplicación Blazor WebAssembly antes de realizar cambios.

En este punto, todas las funcionalidades de la aplicación funcionan tanto si se inicia sesión como si no. Solo los miembros del inquilino de Microsoft Entra ID pueden iniciar sesión.

Paso 3: conceder permisos de API

Para conectarse a Dataverse, debe configurar los permisos para que la aplicación se conecte.

  1. Regrese al registro de la aplicación en Microsoft Entra ID. En la sección Permisos de API, seleccione Agregar un permiso.

    Página de configuración de permisos de API de la aplicación registrada.

  2. En el área Solicitar permisos de API, seleccione API que usa mi organización y busque Dataverse.

    Buscando los permisos de Dataverse.

  3. Seleccione Dataverse.

  4. Seleccione el permiso person_impersonation.

    Añadiendo el permiso user_impersonation de Dataverse.

    Nota

    Dynamics CRM, Common Data Service y Dataverse se refieren al mismo servicio.

  5. Seleccione Agregar permisos.

  6. (Opcional) Para Permisos configurados, seleccione Otorgar consentimiento de administrador para [su nombre de inquilino de Microsoft Entra ID]. En la siguiente captura de pantalla, el nombre del inquilino es "Directorio predeterminado". El suyo puede ser diferente.

    Botón que muestra el botón opcional para otorgar el consentimiento del administrador para la aplicación registrada.

    Si no otorga el consentimiento del administrador aquí, tendrá la opción cuando inicie sesión en la aplicación la próxima vez.

Paso 4: aplicar los cambios de código

Aplique cambios a los siguientes archivos para habilitar la visualización de datos de Dataverse en la aplicación.

\wwwroot\appsettings.json

Aplique los cambios en la siguiente pestaña Después para agregar datos de configuración para su conexión a Dataverse.

  • 22222222-2222-2222-2222-222222222222 representa el id. de inquilino.
  • 11111111-1111-1111-1111-111111111111 representa el valor de ID de la aplicación (cliente) que creó en el registro de su aplicación.
  • Asegúrate de reemplazar https://yourorg.api.crm.dynamics.com con la URL que copiaste anteriormente.
{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/22222222-2222-2222-2222-222222222222",
    "ClientId": "11111111-1111-1111-1111-111111111111",
    "ValidateAuthority": true
  }
}

Program.cs

  1. Instale el paquete NuGet Microsoft.Extensions.Http.

    1. En el explorador de soluciones, haga clic con el botón secundario en el proyecto y seleccione Administrar paquetes de NuGet....
    2. Seleccione Examinar y busque Microsoft.Extensions.Http.
    3. Instale la versión más reciente del paquete.

    Instalar el paquete NuGet necesario.

  2. Reemplace el código generado en la pestaña Antes con el código en la pestaña Después. BlazorSample es el nombre del proyecto que creaste, por lo que varía.

using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorSample;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://graph.microsoft.com/User.Read");
});

await builder.Build().RunAsync();

Agregue \Pages\FetchAccounts.razor

Esta es una nueva página que muestra la información de la cuenta.

  1. En el explorador de soluciones, seleccione Páginas y seleccione Agregar > Componente Razor... en el menú contextual y asígnele el nombre FetchAccounts.razor.

  2. Reemplace el código del archivo con el código siguiente:

    @page "/fetchaccounts"
    @using Microsoft.AspNetCore.Components.WebAssembly.Authentication
    @using System.Net.Http.Headers
    @using System.Net.Http.Json
    @using Microsoft.Extensions.Logging;
    @using System.Text.Json.Serialization;
    @inject IAccessTokenProvider TokenProvider
    @inject IHttpClientFactory ClientFactory
    @inject ILogger<FetchAccounts> logger;
    
    <AuthorizeView>
        @*Only show the list if the user is signed in and authorized*@
        <Authorized>
            <h3>Fetch Accounts</h3>
    
            @if (accounts != null)
            {
                <table class="table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Main Phone</th>
                            <th>City</th>
                            <th>Primary Contact</th>
                            <th>Email (Primary Contact)</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (Account account in accounts.value)
                        {
                            <tr id="@account.accountid">
                                <td>
                                    @((account.name != null)
                                    ? account.name
                                    : string.Empty)
                                </td>
                                <td>
                                    @((account.telephone1 != null)
                                    ? account.telephone1
                                    : string.Empty)
                                </td>
                                <td>
                                    @((account.address1_city != null)
                                    ? account.address1_city
                                    : string.Empty)
                                </td>
                                <td>
                                    @((account.primarycontactid != null)
                                    ? (account.primarycontactid.fullname != null
                                        ? account.primarycontactid.fullname
                                        : string.Empty)
                                    : string.Empty)
                                </td>
                                <td>
                                    @((account.primarycontactid != null)
                                    ? (account.primarycontactid.emailaddress1 !=null
                                        ? account.primarycontactid.emailaddress1
                                        : string.Empty)
                                    : string.Empty)
                                </td>
                            </tr>
                        }
                    </tbody>
                </table>
            }
            else
            {
                <p><em>@message</em></p>
            }
        </Authorized>
        <NotAuthorized>
            <h3>Authentication Failure!</h3>
            <p>You're not signed in.</p>
        </NotAuthorized>
    </AuthorizeView>
    
    
    @code {
    
        //The collection of Account records to display
        private AccountCollection accounts;
    
        //An informational message
        private string message = "Loading...";
    
        //Contains data about an error returned from the Web API
        private Error error;
    
        // Method invoked when the component is ready to start, having received its initial parameters from its parent in the render tree.
        // Override this method if you will perform an asynchronous operation and want the component to refresh when that operation is completed.
        protected override async Task OnInitializedAsync()
        {
            // Tries to get an access token for the current user with the default set of permissions.
            var tokenResult = await TokenProvider.RequestAccessToken();
    
            // If the token request was successful
            if (tokenResult.TryGetToken(out var token))
            {
                //Creates an HttpClient based on the named definition found in Program.Main
                var client = ClientFactory.CreateClient("DataverseClient");
    
                //Prepare the request to get the data
                var request = new HttpRequestMessage()
                {
                    Method = HttpMethod.Get,
                    RequestUri = new Uri($"{client.BaseAddress}accounts?" +
                    "$select=name,telephone1,address1_city&" +
                    "$expand=primarycontactid($select=fullname,emailaddress1)")
                };
                //Add the access token
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Value);
                //Specify a JSON result is expected
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                //Limit the number of results to 10
                request.Headers.Add("Prefer", "odata.maxpagesize=10");
    
                //Send the request
                var response = await client.SendAsync(request);
    
                if (response.IsSuccessStatusCode)
                {
                    //Parse the JSON returned into a strongly typed AccountCollection
                    accounts = await response.Content.ReadFromJsonAsync<AccountCollection>();
                }
                else
                {
                    //Parse the JSON returned into a strongly typed Error
                    error = await response.Content.ReadFromJsonAsync<Error>();
                    error.statuscode = (int)response.StatusCode;
                    error.reason = response.ReasonPhrase;
                    //Display a message to the user
                    message = "An error occurred.";
                    //Log the details so they can be seen in the browser console
                    logger.LogError($"{error.detail.message}");
    
                }
    
            }
            else
            {
                // Notify user that the token request was not successful
                message = "There was a problem authenticating.";
            }
    
        }
    
    
        // The result will be a JSON object with an array of entities set to the value property
        public class AccountCollection
        {
            public Account[] value { get; set; }
        }
    
        //Just the properties of the Account EntityType used for this sample
        // See https://learn.microsoft.com/power-apps/developer/data-platform/webapi/reference/account
        public class Account
        {
    
            public Guid accountid { get; set; }
    
            public string name { get; set; }
    
            public string telephone1 { get; set; }
    
            public string address1_city { get; set; }
    
            public Contact primarycontactid { get; set; }
    
        }
    
        //Just the properties of the Contact EntityType that are expanded from the Account entity
        // See https://learn.microsoft.com/power-apps/developer/data-platform/webapi/reference/contact
        public class Contact
        {
    
            public string fullname { get; set; }
    
            public string emailaddress1 { get; set; }
        }
    
        // Contains the error data returned by the Web API and the HttpMessageResponse
        public class Error
        {
            [JsonPropertyName("error")]
            public ErrorDetail detail { get; set; }
            public int statuscode { get; set; }
            public string reason { get; set; }
    
        }
    
        //Contains data from the Web API
        //See https://learn.microsoft.com/powerapps/developer/data-platform/webapi/compose-http-requests-handle-errors#parse-errors-from-the-response
        public class ErrorDetail
        {
            public string code { get; set; }
            public string message { get; set; }
    
        }
    }
    

Este código hace lo siguiente:

  1. Garantiza que solo los usuarios autenticados puedan ver la página con datos.
  2. Define una tabla para mostrar los datos de la cuenta después de recuperarlos.
  3. Solicita un token de acceso y luego usa ese token con un HttpRequestMessage para recuperar datos de Dataverse.
  4. Define clases para habilitar datos tipados cuando el JSON devuelto por el servicio está deserializado.

\Shared\NavMenu.razor

Edite este archivo para agregar la página del componente fetchaccounts de Razor.

Agregue este nodo donde quiera dentro del elemento <nav class="flex-column">.

<div class="nav-item px-3">
   <NavLink class="nav-link" href="fetchaccounts">
         <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch Accounts
   </NavLink>
</div>

Paso 5: verificar que funciona

En Visual Studio, presione F5 para iniciar la aplicación con los cambios de código.

  1. Antes de iniciar sesión, navegue hasta Obtener cuentas. Debería esperar ver la notificación de error.

  2. Inicie sesión como un usuario que tiene acceso a los datos de Dataverse.

    Nota

    Los usuarios pueden esperar ver un cuadro de diálogo como este la primera vez que inician sesión:

    Cuadro de diálogo para solicitar al usuario que otorgue consentimiento para la aplicación.

    Para continuar, debe hacer clic en Aceptar.

  3. Navegue a Obtener cuentas y verifique que los datos de la cuenta se muestren como era previsto:

    Comportamiento final esperado para completar con éxito el tutorial.

Consultar también

Utilice el servicio de detección global desde un Blazor WebAssembly
Inicio rápido: muestra de API web de Blazor Server (C#)
Proteger una aplicación independiente ASP.NET Core Blazor WebAssembly con Microsoft Entra ID
Tutorial: Registrar una aplicación con Microsoft Entra ID
Utilizar OAuth con Dataverse
Usar la API web de Dataverse

Nota

¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)

La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).