Nota
O acceso a esta páxina require autorización. Pode tentar iniciar sesión ou modificar os directorios.
O acceso a esta páxina require autorización. Pode tentar modificar os directorios.
Al crear un mensaje de Microsoft Dataverse mediante una API personalizada, debe especificar el nombre y el tipo de datos de cada uno de los parámetros de solicitud y las propiedades de respuesta. Los tipos de datos se pueden abrir o cerrar. Con los tipos cerrados, se conoce cada nombre de propiedad y valor de tipo. Se cierran todos los tipos definidos en Dataverse. El sistema conoce los tipos cerrados y puede validarlos por usted. Si usa el nombre incorrecto o establece el valor en el tipo incorrecto, obtendrá un error. Pero los tipos cerrados no son dinámicos. No permiten propiedades complejas y anidadas. Normalmente, una estructura específica es una buena cosa, pero a veces la lógica de negocios requiere un enfoque más flexible.
A diferencia de los tipos cerrados, los tipos abiertos pueden tener propiedades dinámicas. El uso de tipos abiertos con API personalizadas tiene sentido cuando:
- Debe usar datos dinámicos estructurados. Estos datos no se pueden describir mediante una clase, por lo que no es necesario serializarlos ni deserializarlos.
- Quiere que una API personalizada acepte un parámetro de solicitud o devuelva una propiedad de respuesta que tenga un tipo complejo que no se pueda expresar mediante las opciones disponibles. En ese caso, debe usar un tipo cerrado personalizado.
Es importante comprender el escenario que se aplica a la API personalizada para usar los tipos abiertos correctamente. En primer lugar, vamos a comprender cómo usar los tipos abiertos.
Uso de tipos abiertos
Para usar tipos abiertos, necesita un mensaje que esté configurado para ellos. Con una API personalizada, usted especifica que un parámetro de solicitud o una propiedad de respuesta está abierto estableciendo el Type como Entity (3) o EntityCollection (4) sin especificar el LogicalEntityName.
Cuando no se especifica LogicalEntityName, se indica a Dataverse que Entity es una colección de pares clave-valor que no se pueden validar con ninguna definición de tabla, por lo que no intenta hacerlo. Una EntityCollection sin LogicalEntityName es solo una matriz de Entity.
Nota:
Una API personalizada definida como funciones no puede usar tipos abiertos como parámetros de solicitud, pero puede usarlos como propiedades de respuesta.
Uso de entidades de Dataverse
Aunque en realidad no es un tipo abierto, merece la pena mencionar que puede tener una API personalizada con parámetros o propiedades de respuesta que representen más de un tipo de entidad cerrado. Por ejemplo, puede crear una API personalizada con un parámetro Customer que espera instancias de entidades Account o Contact. Dataverse permite cualquier tipo de entidad. El código del complemento debe comprobar el valor Entity.LogicalName para determinar si es un tipo esperado.
Uso de Entity como diccionario
El caso más común es usar Entity como diccionario. Use la colección Entity.Attributes para especificar un conjunto de claves y valores. Los valores pueden ser de cualquier tipo .NET y se pueden anidar. No use ninguna otra propiedad de clase Entity .
Supongamos que la aplicación usa datos procedentes de o que se envían a Microsoft Graph y representa el tipo de recurso educationSchool. Puede usar un tipo abierto como en los ejemplos siguientes.
Para usar un tipo abierto con el SDK, use la clase Entity sin especificar el nombre de la entidad y, a continuación, establezca la colección Entity.Attributes con las claves y sus valores.
var educationSchool = new Entity() {
Attributes =
{
{ "id", Guid.NewGuid() },
{ "displayName","Redmond STEM Academy" },
{ "phone", "555-1234" },
{ "address", new Entity() //physicalAddress resource type
{
Attributes =
{
{ "city","Redmond" },
{ "countryOrRegion","United States" },
{ "postalCode","98008" },
{ "state","Washington" },
{ "street","123 Maple St" },
}
}
}
}
};
Usar tipos de Dataverse
Además de los tipos básicos de .NET, también puede usar tipos conocidos para Dataverse. El SDK para .NET contiene definiciones de muchas clases sobre las que Dataverse tiene información, y en la API web, estos tipos se enumeran en la Referencia de Tipo Complejo y Referencia de Tipo de Enumeración.
Al usar el SDK, simplemente puede establecer los valores.
Al usar la API web, debe especificar el tipo mediante el espacio de nombres de la API web: Microsoft.Dynamics.CRM. En el ejemplo siguiente se usan estos tipos de API web de Dataverse:
{
"@odata.type": "Microsoft.Dynamics.CRM.expando",
"label@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"label": {
"Label": "Yes",
"LanguageCode": 1033
},
"labelarray": [
{
"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "test",
"LanguageCode": 1033
},
{
"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "prøve",
"LanguageCode": 1030
}
],
"labelarray@odata.type": "Collection(Microsoft.Dynamics.CRM.LocalizedLabel)",
"enumarray": ["DateOnly"],
"enumarray@odata.type": "Collection(Microsoft.Dynamics.CRM.DateTimeFormat)"
}
Datos dinámicos estructurados
Los datos dinámicos estructurados se pueden definir mediante varios formatos que se pueden establecer como una cadena, como JSON, XML, YAML y HTML. Este tipo de datos se puede establecer fácilmente mediante un parámetro de cadena o una propiedad de respuesta. ¿Por qué usar tipos abiertos?
- Use una cadena cuando los datos estructurados se pasen a través de la API personalizada a otro servicio o se consuman como una cadena por otra aplicación que llame a la API personalizada.
- Use un tipo abierto cuando el complemento que admita la API personalizada, o cualquier complemento que extienda la API personalizada, debe leer o cambiar los datos estructurados.
Analizar un valor de cadena en un objeto como XDocument o JObject para que pueda manipularlo en el complemento es una operación relativamente costosa. Cuando el complemento, o cualquier otro complemento que pueda extender la lógica en la API personalizada, cambia los datos, debe convertir el objeto en una cadena. Puede evitar estas operaciones costosas mediante el uso de tipos abiertos.
Con los tipos abiertos, los autores de llamadas de la API personalizada pueden usar la estructura de diccionario conocida que proporciona la clase Entity . El complemento puede interactuar con él de la misma manera que trabaja con otros registros de Dataverse.
Si estás serializando o deserializando los datos en formato de cadena a una clase, tus datos no son dinámicos. Debería revisar la siguiente sección.
Tipos cerrados personalizados
Los tipos abiertos permiten datos dinámicos y no estructurados. Pero debe tener en cuenta si la API tiene parámetros realmente dinámicos o si realmente desea tener un tipo personalizado.
Actualmente, no se puede definir un tipo personalizado que Dataverse conozca. Pero con tipos abiertos, puede definir una clase de tipo cerrado que Dataverse puede procesar como un tipo abierto. Los desarrolladores que usan la API personalizada pueden usar sus clases para tener una experiencia mejor y más productiva con menos oportunidades de errores.
Por ejemplo, supongamos que la API personalizada requiere un parámetro que realice un seguimiento de un curso mediante una matriz de coordenadas de latitud y longitud. Necesita una clase de Location.
Puede crear una Location clase que herede de la clase Entity y contiene las propiedades que necesita. Por ejemplo:
using Microsoft.Xrm.Sdk;
namespace MyCompany
{
/// <summary>
/// Specifies a location for use with my_CustomAPI
/// </summary>
public class Location : Entity
{
// Gets or sets the latitude of the Location.
[AttributeLogicalName("Latitude")]
public double Latitude
{
get
{
return GetAttributeValue<double>("Latitude");
}
set
{
SetAttributeValue("Latitude", value);
}
}
// Gets or sets the longitude of the Location.
[AttributeLogicalName("Longitude")]
public double Longitude
{
get
{
return GetAttributeValue<double>("Longitude");
}
set
{
SetAttributeValue("Longitude", value);
}
}
}
}
Dado que este tipo hereda de la Entity clase , puede usar los Entity métodos GetAttributeValue y SetAttributeValue para tener acceso a los valores de la Attributes colección. Puede usar esta clase en el código del complemento y compartirla con los consumidores en una biblioteca o en código de ejemplo en la documentación. El resultado es código que es más fácil de usar y leer.
Before:
var location = new Entity() {
Attributes =
{
{ "Latitude", 47.66132951804776 },
{ "Longitude", -122.11446844957624},
}
};
// OR
var location = new Entity();
location["Latitude"] = 47.66132951804776;
location["Longitude"] = -122.11446844957624;
After:
var location = new Location {
Latitude = 47.66132951804776,
Longitude = -122.11446844957624
};
// OR
var location = new Location()
location.Latitude = 47.66132951804776;
location.Longitude = -122.11446844957624;
Problemas conocidos
Error al usar datos de matriz con web API
Cuando se usa la API web para enviar datos que contienen una matriz, se produce el siguiente error cuando la API personalizada tiene un complemento:
{
"error": {
"code": "0x80040224",
"message": "Element 'http://schemas.datacontract.org/2004/07/System.Collections.Generic:value' contains
data from a type that maps to the name 'System.Collections.Generic:List`1'. The deserializer has no
knowledge of any type that maps to this name. Consider changing the implementation of the ResolveName
method on your DataContractResolver to return a non-null value for name 'List`1' and namespace
'System.Collections.Generic'.",
}
}
Este error no se produce cuando la aplicación cliente usa el SDK para .NET o cuando no se establece ningún complemento para la API personalizada.
Use el botón Comentarios de esta página a continuación para enviar preguntas que tenga sobre los tipos abiertos.
Consulte también
Crear y usar API personalizadas
tutorial avanzado de Odata.org: Tipo abierto