Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
WebAPIService es un proyecto de biblioteca de clases de .NET 6.0 de muestra que muestra varias capacidades importantes que debe incluir al usar la API web de Dataverse.
Esta biblioteca demuestra:
- Administrar los límites de protección del servicio de Dataverse con la resiliencia de .NET y la biblioteca de gestión de errores transitorios Polly.
- Administrar un HttpClient en .NET usando IHttpClientFactory.
- Usar datos de configuración para gestionar el comportamiento del cliente.
- Administrar los errores devueltos por la API web de Dataverse.
- Un patrón de reutilización de código mediante:
- Creando clases que heredan de HttpRequestMessage y HttpResponseMessage.
- Métodos que usan esas clases.
- Un patrón modular para agregar nuevas capacidades según sea necesario.
Nota
Esta biblioteca de muestras es una ayuda que utilizan todos los ejemplos de API web de C# de Dataverse, pero no es un SDK. Se prueba solo para confirmar que las muestras que lo usan se ejecutan correctamente. Este código de muestra se proporciona 'tal cual' sin garantía de reutilización.
Esta biblioteca no:
- Administrar la autenticación. Depende de una función pasada desde una aplicación que proporciona el token de acceso para usar. Todos los ejemplos de Web API dependen de una clase de aplicación que gestiona la autenticación mediante la Biblioteca de autenticación de Microsoft (MSAL). MSAL admite varios tipos diferentes de flujos de autenticación. Estos ejemplos usan el flujo Nombre de usuario/contraseña (ROPC) por simplicidad, pero no se recomienda este flujo. Para sus aplicaciones, debe usar uno de los otros flujos. Más información: Compatibilidad con el flujo de autenticación en la biblioteca de autenticación de Microsoft.
- Proporcionar cualquier capacidad de generación de código. Todas las clases utilizadas en las muestras están escritas a mano. Todos los datos de entidades comerciales utilizan la conocida clase Json.NET JObject en lugar de una clase que representa el tipo de entidad.
- Proporcionar un modelo de objetos para componer consultas de OData. Todas las consultas muestran la sintaxis de consulta de OData como parámetros de consulta.
Código
Puede encontrar el código fuente de la biblioteca de clases WebApiService y la solución Visual Studio en PowerApps-Samples/dataverse/webapi/C#-NETx/WebAPIService
Lista de clases
En WebAPIService se incluyen las siguientes clases.
Clase Service
La clase Service proporciona métodos para enviar solicitudes a Dataverse a través de un HttpClient administrado usando IHttpClientFactory.
El Service es el componente principal de todos los ejemplos y puede usarlo para completar cualquier operación demostrada con código de muestra. Todo lo demás que esté incluido en el WebAPIService o cualquiera de las muestras que lo utilizan proporciona la reutilización del código y permite las capacidades de la API web de Dataverse que se demostrará en un nivel superior.
El constructor Service acepta una instancia de clase Config que contiene dos propiedades requeridas: GetAccessToken y Url. Todas las demás propiedades representan opciones que tienen valores predeterminados.
El constructor utiliza la inyección de dependencia para crear un IHttpClientFactory que puede devolver un HttpClient con nombre con las propiedades especificadas en la función ConfigureHttpClient. El hecho de que este cliente utilice o no cookies se basa en si el parámetro Config.DisableCookies está configurado. En el constructor la directiva definida por el método estático GetRetryPolicy que controla cómo se gestionan los errores transitorios y los límites de protección de servicio de Dataverse.
Métodos de servicio
La clase Service tiene los métodos siguientes:
Método SendAsync
Este método es el responsable final de todas las operaciones.
Este método:
- Tiene un parámetro HttpRequestMessage.
- Devuelve
Task<HttpResponseMessage> - Expone la misma firma que el método HttpClient.SendAsync(HttpRequestMessage) y se puede usar de la misma manera.
- Llama a la función configurada en el método
Config.GetAccessTokenpara establecer el valor de encabezadoAuthorizationpara la solicitud. - Utiliza el método IHttpClientFactory.CreateClient para obtener el
HttpClientcon nombre para enviar la solicitud. - Lanza un ServiceException si la propiedad HttpResponseMessage.IsSuccessStatusCode es falsa, por lo que no es necesario comprobar el
IsSuccessStatusCodeal utilizar este método.
Método SendAsync<T>
Este método facilita la devolución de una clase que incluye propiedades que se encuentran en los ComplexTypes devueltos por acciones y funciones de OData en la API web de Dataverse.
- Tiene un parámetro HttpRequestMessage. Cuando se usa este método se espera, pero no se requiere, que el parámetro de solicitud sea una de las *clases de respuesta que se derivan de
HttpResponseMessage. - Devuelve
Task<T>dondeTes una clase derivada deHttpResponseMessage. Para obtener más información, consulte *Clases de respuesta. - Llama al método SendAsync.
- Utiliza el método de extensión HttpResponseMessage As<T> para devolver el tipo solicitado.
En el siguiente ejemplo se muestra cómo usar la función WhoAmI.
static async Task WhoAmI(Service service)
{
var response = await service.SendAsync<WhoAmIResponse>(new WhoAmIRequest());
Console.WriteLine($"Your user ID is {response.UserId}");
}
Método ParseError
Este método analiza el contenido de un HttpResponseMessage por un fracaso de HttpRequestMessage para devolver un ServiceException. El método SendAsync utiliza este método cuando la propiedad HttpResponseMessage.IsSuccessStatusCode es falsa. También se puede usar para extraer información de error de las instancias devueltas de HttpResponseMessage por BatchResponse.HttpResponseMessages cuando la propiedad BatchRequest.ContinueOnError se establece en true. Más información: Batch
Propiedades del servicio
Service tiene una sola propiedad: BaseAddress.
Propiedad BaseAddress
Esta propiedad devuelve la URL base establecida en Config.Url. Necesita esta URL al crear una instancia de la clase BatchRequest y para anexar a una URL relativa cada vez que se requiera una URL absoluta.
Clase Config
La clase Config contiene propiedades que controlan el comportamiento de la aplicación como se muestra en la siguiente tabla:
| Propiedad | Tipo | Descripción |
|---|---|---|
GetAccessToken |
Func<Task<string>> |
Una función proporcionada por la aplicación cliente para devolver un token de acceso. |
Url |
string? |
URL base del entorno. Por ejemplo: https://org.api.crm.dynamics.com |
CallerObjectId |
Guid |
Valor SystemUser.ActiveDirectoryGuid para aplicar para la suplantación de identidad. El valor predeterminado es Guid.Empty Más información: Suplantar a otro usuario utilizando la API web |
TimeoutInSeconds |
ushort |
Cuánto tiempo esperar un tiempo de espera. El valor predeterminado es 120 segundos. |
MaxRetries |
byte |
Número máximo de veces para volver a intentar cuando se llega a los límites de protección del servicio. El valor predeterminado es 3. |
Version |
string |
La versión del servicio que se va a utilizar. El valor predeterminado es v9.2 |
DisableCookies |
bool |
Si se deshabilitan las cookies para ganar rendimiento en escenarios de carga masiva de datos. Más información: Afinidad del servidor |
Clase EntityReference
La clase EntityReference representa una referencia a un registro en una tabla de Dataverse. OData identifica recursos con una URL.
EntityReference proporciona métodos para facilitar la creación y el acceso a las propiedades de las URL.
Constructores de EntityReference
Utilice los siguientes constructores para instanciar una EntityReference.
EntityReference(string entitySetName, Guid? ID)
Crea una referencia de entidad usando EntitySetName y Guid.
EntityReference(string uri)
Analiza una URL absoluta o relativa para crear una referencia de entidad, incluidas las URL que usan claves alternativas.
EntityReference(string setName, Dictionary<string, string>? keyAttributes)
Use este constructor para instanciar una referencia de entidad usando un clave alternativa.
Nota
Los valores clave deben ser valores de cadena. Esto no convierte otros tipos en cadenas apropiadas.
Propiedades de EntityReference
EntityReference tiene las siguientes propiedades públicas:
| Propiedad | Tipo | Descripción |
|---|---|---|
Id |
Guid? |
El valor de la clave principal del registro cuando no se usa un clave alternativa. |
KeyAttributes |
Dictionary<string, string> |
Los valores de cadena que representan los valores clave alternativa utilizados en una URL. |
SetName |
string |
EntitySetName del tipo de entidad. |
Path |
string |
URL relativa del registro. |
Métodos EntityReference
EntityReference tiene los siguientes métodos públicos: Ninguno de ellos requiere ningún parámetro.
| Nombre del método | Tipo devuelto | Descripción |
|---|---|---|
AsODataId |
string |
Devuelve una cadena formateada para usar como referencia de parámetro a un registro en la URL para una función OData. |
AsJObject |
JObject |
Devuelve un JObject que se puede utilizar como referencia de parámetro para un registro en una acción OData. |
Clases de errores
ODataError, Error y ODataException son clases utilizadas para deserializar errores devueltos por el servicio. No es necesario trabajar con ellos directamente.
ServiceException
ServiceException es una clase de excepción que contiene propiedades del error devuelto por el servicio. Utilice el método ParseError para obtener una instancia de esta excepción.
Extensiones
WebApiService tiene un método de extensión de un tipo .NET.
HttpResponseMessage As<T>
Esta extensión crea una instancia de T dónde T se deriva de HttpResponseMessage y copia las propiedades de HttpResponseMessage en la clase derivada. El método ServiceSendAsync<T> utiliza este método, pero también se puede utilizar por separado. Por ejemplo, cuando se utiliza la clase BatchRequest, los elementos del BatchResponse.HttpResponseMessages son tipos HttpResponseMessage. Puede usar esta extensión para convertirlos a la clase derivada apropiada para facilitar el acceso a cualquier propiedad.
Mensajes
La carpeta Messages incluye clases que heredan de HttpRequestMessage o HttpResponseMessage.
Estas clases proporcionan definiciones reutilizables de solicitudes y respuestas que corresponden a operaciones de OData que puede usar en cualquier entorno de Dataverse.
Estas clases también proporcionan ejemplos de operaciones específicas que se pueden aplicar usando HttpRequestMessage y HttpResponseMessage sin derivar de esos tipos.
Dentro de una aplicación, también puede crear mensajes personalizados, por ejemplo, representando una API personalizada en su entorno, utilizando el mismo patrón. Estas son clases modulares y no es necesario incluirlas en la carpeta WebAPIService.Messages.
Por ejemplo, el ejemplo de acciones y funciones de API web (C#) utiliza una API personalizada que no está incluida en Dataverse hasta que se instale una solución que contenga la API personalizada. La definición de las clases correspondientes para usar este mensaje se encuentra en la aplicación de muestra que lo usa:
- FunctionsAndActions/Messages/IsSystemAdminRequest.cs
- FunctionsAndActions/Messages/IsSystemAdminResponse.cs
Clases *Request
Estas clases generalmente tienen un constructor con parámetros que crea una instancia de un HttpRequestMessage con los datos necesarios para realizar la operación. Pueden tener propiedades separadas según corresponda.
El ejemplo más simple de este patrón es la clase WhoAmIRequest.
namespace PowerApps.Samples.Messages
{
/// <summary>
/// Contains the data to perform the WhoAmI function
/// </summary>
public sealed class WhoAmIRequest : HttpRequestMessage
{
/// <summary>
/// Initializes the WhoAmIRequest
/// </summary>
public WhoAmIRequest()
{
Method = HttpMethod.Get;
RequestUri = new Uri(
uriString: "WhoAmI",
uriKind: UriKind.Relative);
}
}
}
Por lo general, los nombres de estas clases se alinean con las clases en el espacio de nombres Microsoft.Xrm.Sdk.Messages del SDK de Dataverse, pero no se limitan a esas operaciones. La API web permite realizar algunas operaciones que no se pueden realizar con el SDK, por ejemplo CreateRetrieveRequest es un mensaje que crea un registro y lo recupera. El SDK de Dataverse no proporciona esta capacidad en una sola solicitud.
Clases *Response
Cuando las clases *Request devuelven un valor, hay una clase *Response correspondiente para acceder a las propiedades devueltas. Si *Request devuelve 204 No Content, la operación devuelve un HttpResponseMessage, pero no hay ninguna clase derivada. Utilice el método SendAsync para enviar estas solicitudes.
Las clases *Response proporcionan propiedades con tipo que acceden a las propiedades HttpResponseMessageHeaders o Content y las analiza para proporcionar acceso al tipo complejo devuelto por la operación.
La clase WhoAmIResponse es un ejemplo. Dentro de esta clase se puede encontrar todo el código necesario para extraer las propiedades del ComplexType WhoAmIResponse.
using Newtonsoft.Json.Linq;
namespace PowerApps.Samples.Messages
{
// This class must be instantiated by either:
// - The Service.SendAsync<T> method
// - The HttpResponseMessage.As<T> extension in Extensions.cs
/// <summary>
/// Contains the response from the WhoAmIRequest
/// </summary>
public sealed class WhoAmIResponse : HttpResponseMessage
{
// Cache the async content
private string? _content;
//Provides JObject for property getters
private JObject _jObject
{
get
{
_content ??= Content.ReadAsStringAsync().GetAwaiter().GetResult();
return JObject.Parse(_content);
}
}
/// <summary>
/// Gets the ID of the business to which the logged on user belongs.
/// </summary>
public Guid BusinessUnitId => (Guid)_jObject.GetValue(nameof(BusinessUnitId));
/// <summary>
/// Gets ID of the user who is logged on.
/// </summary>
public Guid UserId => (Guid)_jObject.GetValue(nameof(UserId));
/// <summary>
/// Gets ID of the organization that the user belongs to.
/// </summary>
public Guid OrganizationId => (Guid)_jObject.GetValue(nameof(OrganizationId));
}
}
Estas clases solo se pueden crear instancias correctamente cuando las devuelve el Método SendAsync<T> o mediante la extensión HttpResponseMessage As<T> en un HttpResponseMessage en la propiedad BatchResponse.HttpResponseMessages.
Lote
La carpeta Batch contiene tres clases para gestionar el envío de solicitudes OData $batch. Más información:Ejecute las operaciones por lotes mediante API web
BatchRequest
El constructor BatchRequest inicializa un HttpRequestMessage que se puede usar con el método SendAsync<T> para enviar solicitudes en lotes. El constructor requiere que se pase el valor Service.BaseAddress como parámetro.
BatchRequest tiene las siguientes propiedades.
| Property | Tipo | Descripción |
|---|---|---|
ContinueOnError |
Bool |
Controla si la operación por lotes debe continuar cuando se produce un error. |
ChangeSets |
List<ChangeSet> |
Uno o más conjuntos de cambios que se incluirán en el lote. |
Requests |
List<HttpRequestMessage> |
Uno o mas HttpMessageRequest para enviar fuera de cualquier ChangeSet. |
Cuando ChangeSets o Requests están configurados, están encapsulados en HttpMessageContent y se añaden al Content de la solicitud. El método ToMessageContent privado aplica los cambios requeridos a los encabezados y devuelve el HttpMessageContent para las propiedades ChangeSets y Requests.
ChangeSet
Un conjunto de cambios representa un grupo de solicitudes que deben completarse dentro de una transacción.
Contiene una sola propiedad:
| Property | Tipo | Descripción |
|---|---|---|
Requests |
List<HttpRequestMessage> |
Uno o mas HttpMessageRequest para realizar dentro de la transacción. |
BatchResponse
BatchResponse tiene una sola propiedad:
| Property | Tipo | Descripción |
|---|---|---|
HttpResponseMessages |
List<HttpResponseMessage> |
Las respuestas de la operación $batch. |
BatchResponse tiene un método privado ParseMultipartContent utilizado por el captador de la propiedad HttpResponseMessages para analizar el MultipartContent devuelto al HttpResponseMessage individual.
Para acceder a las propiedades de tipo de las instancias de HttpResponseMessage devueltas, puede usar el método de extensión HttpResponseMessage As<T>.
Métodos
Para las operaciones que se realizan con frecuencia, la carpeta Methods contiene extensiones de la clase Service. Estos métodos permiten utilizar las clases *Request correspondientes en una sola línea.
Se incluyen los siguientes métodos:
| método | Tipo devuelto | Descripción |
|---|---|---|
Create |
Task<EntityReference> |
Crea un nuevo registro. |
CreateRetrieve |
Task<JObject> |
Crea un nuevo registro y lo recupera. |
Delete |
Task |
Elimina un registro. |
FetchXml |
Task<FetchXmlResponse> |
Recupera los resultados de una consulta FetchXml. La solicitud se envía con POST usando $batch para mitigar los problemas en los que las URL largas se envían con GET puede exceder los límites. |
GetColumnValue<T> |
Task<T> |
Recupera un único valor de columna de una fila de tabla. |
Retrieve |
Task<JObject> |
Recupera un registro. |
RetrieveMultiple |
Task<RetrieveMultipleResponse> |
Recupera múltiples registros. |
SetColumnValue<T> |
Task |
Establece el valor de una columna para una fila de tabla. |
Update |
Task |
Actualiza un registro. |
Upsert |
Task<UpsertResponse> |
Realiza un Upsert en un registro. |
Dentro de una aplicación de ejemplo que utiliza WebAPIService, cuando la operación no representa una API que se encuentra en Dataverse de forma predeterminada, el método se define en la aplicación en lugar de en WebAPIService.
Por ejemplo, el ejemplo de acciones y funciones de API web (C#) utiliza una API personalizada que no está incluida en Dataverse hasta que se instale una solución que contenga la API personalizada. La definición de este método se encuentra en la aplicación de muestra que lo utiliza: FunctionsAndActions/Methods/IsSystemAdmin.cs
Tipos
La Types carpeta contiene las clases o enumeraciones que corresponden a ComplexTypes o EnumTypes necesarias como parámetros o propiedades de respuesta para los mensajes.
Metadata
La carpeta Metadata contiene Messages y Types específicos para operaciones que trabajan con definiciones de esquemas de Dataverse. Estas clases suelen tener muchas propiedades que devuelven tipos complejos. Estos tipos se utilizan en el ejemplo de operaciones de esquema de tabla de API web (C#).
Vea también
Ejemplo de operaciones básicas de la API web (C#)
Ejemplo de datos de consulta de API web (C#)
Ejemplo de operaciones condicionales de la API web (C#)
Ejemplo de funciones y acciones de la API web (C#)
Ejemplo de operaciones de esquema de tabla de API web (C#)
Ejemplo de operaciones en paralelo de la API web WebApiService (C#)
Ejemplo de operaciones paralelas de API web con componentes de flujo de datos TPL (C#)