Biblioteca de clases WebAPIService (C#)
WebAPIService
es un proyecto de biblioteca de clases .NET 6.0 de muestra que demuestra varias capacidades importantes que debe incluir al utilizar 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 manejo de fallas transitorias Polly.
- Administrar un HttpClient en .NET usando IHttpClientFactory.
- Usar datos de configuración para gestionar el comportamiento del cliente.
- Gestionar 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:
- Administra 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á a 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 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.GetAccessToken
para establecer el valor de encabezadoAuthorization
para la solicitud. - Utiliza el método IHttpClientFactory.CreateClient para obtener el
HttpClient
con nombre para enviar la solicitud. - Lanza un ServiceException si la propiedad HttpResponseMessage.IsSuccessStatusCode es falsa, por lo que no es necesario comprobar el
IsSuccessStatusCode
al 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 OData Actions and Functions 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>
dondeT
es 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.
El siguiente ejemplo muestra el uso con WhoAmI function:
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 Service
SendAsync<T> Método 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);
}
}
}
Los nombres de estas clases generalmente se alinean con las clases en el Dataverse SDK Microsoft.Xrm.Sdk.Messages Namespace 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 HttpResponseMessage
Headers
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 puede encontrar todo el código necesario para extraer las propiedades de WhoAmIResponse ComplexType.
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 | Type | 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 | Type | Descripción |
---|---|---|
Requests |
List<HttpRequestMessage> |
Uno o mas HttpMessageRequest para realizar dentro de la transacción. |
BatchResponse
BatchResponse
tiene una sola propiedad:
Property | Type | 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
indivicual.
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 muestra 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 carpeta Types
contiene clases o enumeraciones que corresponden a ComplexTypes o EnumTypes necesarios 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#).
Consulte 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#)
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).