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.
Este artículo amplía el artículo Quick Start Web API with PowerShell para describir las funcionalidades avanzadas mediante PowerShell y Visual Studio Code con Dataverse Web API para:
- Creación de funciones reutilizables
- Control de excepciones
- Administración de límites de protección del servicio Dataverse
- Depuración mediante Fiddler
- Descargar el documento de $metadata CSDL de la API web de Dataverse
Nota:
Las instrucciones de este artículo deben funcionar para Windows, Linux y macOS, pero estos pasos solo se han probado en Windows. Si se necesitan cambios, háganoslo saber mediante la sección Comentarios en la parte inferior de este artículo.
Prerrequisitos
El contenido de este artículo tiene los mismos requisitos previos que el artículo Quick Start Web API con PowerShell .
Instale o verifique que lo siguiente esté instalado
Instale Visual Studio Code. Consulte Descargar Visual Studio Code
Instale la extensión de PowerShell para Visual Studio Code. Consulte PowerShell para Visual Studio Code
Instale PowerShell 7.4 o superior. Consulte Instalar PowerShell en Windows, Linux y macOS
Instale el módulo Az PowerShell versión 11.1.0 o superior. Consulte Instalar Azure PowerShell
Para actualizar una instalación existente a la última versión, use
Update-Module -Name Az -Force
Verificar instalación
Abre Visual Studio Code.
En el menú Terminal, seleccione Nuevo terminal.
En el panel de navegación de Visual Studio Code, seleccione el icono
para la extensión de PowerShell.Copie y pegue el siguiente script en la ventana de la terminal de Visual Studio Code:
Write-Host 'PowerShell Version:'$PSVersionTable.PSVersion.ToString() Write-Host 'PowerShell Az version:'(Get-InstalledModule Az).VersionPresione ENTRAR. El resultado debería similar al siguiente:
PowerShell Version: 7.4.0 PowerShell Az version: 11.1.0
Si no ve resultados como este, instale o actualice los requisitos previos.
También necesitará
- Cuenta de usuario válida para un entorno de Dataverse
- Dirección URL al entorno de Dataverse al que desea conectarse Consulte Ver recursos para desarrolladores para saber cómo encontrarlo. Se parece a esto:
https://yourorg.crm.dynamics.com/, dondeyourorg.crmes diferente. - Comprensión básica de lenguaje de scripting PowerShell
Creación de funciones reutilizables
La API web de inicio rápido con PowerShell introdujo cómo autenticar y llamar a la función WhoAmI con Visual Studio Code. Este enfoque puede ser todo lo que necesita para una prueba ad hoc de una o varias operaciones. Sin embargo, a medida que los scripts se vuelven más complejos, es posible que escriba el mismo código de nuevo y de nuevo.
En esta sección, empezamos a crear un conjunto de funciones reutilizables en archivos independientes a los que podemos acceder mediante dot sourcing. Utilice el origen de puntos para cargar un archivo que contenga scripts de PowerShell que puedan contener funciones y variables que pasen a formar parte del alcance del script local.
Sugerencia
Puede encontrar definiciones totalmente documentadas de estas funciones y mucho más en nuestro repositorio de PowerApps-Samples de GitHub en PowerApps-Samples/dataverse/webapi/PS/
Creación de una función Connect
Vamos a colocar el código para autenticarse en Dataverse en una función denominada Connect dentro de un archivo denominado Core.ps1 para poder reutilizarlo en una sola línea de código.
Crear una carpeta. En este ejemplo, creamos una carpeta en
C:\scripts.Cree un archivo de texto en la carpeta scripts denominada
Core.ps1.Copie y pegue la siguiente
Connectfunción en elCore.ps1archivo.function Connect { param ( [Parameter(Mandatory)] [String] $environmentUrl ) ## Login interactively if not already logged in if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) { Connect-AzAccount | Out-Null } # Get an access token $secureToken = (Get-AzAccessToken ` -ResourceUrl $environmentUrl ` -AsSecureString).Token # Convert the secure token to a string $token = ConvertFrom-SecureString ` -SecureString $secureToken ` -AsPlainText # Define common set of headers $global:baseHeaders = @{ 'Authorization' = 'Bearer ' + $token 'Accept' = 'application/json' 'OData-MaxVersion' = '4.0' 'OData-Version' = '4.0' } # Set baseURI $global:baseURI = $environmentUrl + 'api/data/v9.2/' }Nota:
El script agrega las
baseURIvariables ybaseHeadersal contexto global mediante el$globalmodificador de ámbito para que estén disponibles para otros scripts en la misma sesión.Cree otro archivo de texto en Visual Studio Code denominado
test.ps1en lascriptscarpeta.Copie y pegue el siguiente script en el
test.ps1archivo:. $PSScriptRoot\Core.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Invoke WhoAmI Function Invoke-RestMethod -Uri ($baseURI + 'WhoAmI') -Method Get -Headers $baseHeaders | ConvertTo-Json. $PSScriptRoot\Core.ps1en la parte superior del archivo se usa dot sourcing para dirigir el script para cargar el contenido de ese archivo.Recuerde cambiar
https://yourorg.crm.dynamics.com/para que coincida con la dirección URL de su entorno.Para ejecutar el script, presione F5.
La salida podría ser similar a esta salida:
PS C:\scripts> . 'C:\scripts\test.ps1' { "@odata.context": "https://yourorg.crm.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse", "BusinessUnitId": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff", "UserId": "22cc22cc-dd33-ee44-ff55-66aa66aa66aa", "OrganizationId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee" }
Creación de una función WhoAmI
Vamos a colocar el código para invocar la función WhoAmI en una función denominada Get-WhoAmI dentro de un archivo denominado CommonFunctions.ps1 para que podamos escribir solo 11 caracteres en lugar de 100 cada vez que quiera usar la función WhoAmI.
Cree un nuevo archivo de texto denominado
CommonFunctions.ps1en lascriptscarpeta.Copie y pegue la siguiente definición de función en el
CommonFunctions.ps1.function Get-WhoAmI{ $WhoAmIRequest = @{ Uri = $baseURI + 'WhoAmI' Method = 'Get' Headers = $baseHeaders } Invoke-RestMethod @WhoAmIRequest }Nota:
Esta definición de función utiliza una técnica llamada splatting. Splatting hace que sus comandos sean más cortos y más fáciles de leer porque pasa una colección de valores de parámetros a un comando como una unidad.
Guarde el archivo
CommonFunctions.ps1.Cambie el
test.ps1archivo para que tenga un aspecto similar al siguiente script:. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Invoke WhoAmI Function Get-WhoAmI | ConvertTo-JsonRecuerde cambiar el
https://yourorg.crm.dynamics.com/valor para que coincida con la dirección URL de su entorno.Para ejecutar el script, presione F5.
La salida debe tener exactamente el mismo aspecto que tenía antes.
Creación de funciones de operaciones de tabla
Vamos a colocar funciones para realizar operaciones de tabla comunes un archivo denominado TableOperations.ps1 para que podamos reutilizarlas.
Cree un nuevo archivo de texto denominado
TableOperations.ps1en lascriptscarpeta.Copie y pegue las siguientes definiciones de función en el
TableOperations.ps1.function Get-Records { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [String] $query ) $uri = $baseURI + $setName + $query # Header for GET operations that have annotations $getHeaders = $baseHeaders.Clone() $getHeaders.Add('If-None-Match', $null) $getHeaders.Add('Prefer', 'odata.include-annotations="*"') $RetrieveMultipleRequest = @{ Uri = $uri Method = 'Get' Headers = $getHeaders } Invoke-RestMethod @RetrieveMultipleRequest } function New-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [hashtable] $body ) $postHeaders = $baseHeaders.Clone() $postHeaders.Add('Content-Type', 'application/json') $CreateRequest = @{ Uri = $baseURI + $setName Method = 'Post' Headers = $postHeaders Body = ConvertTo-Json $body } Invoke-RestMethod @CreateRequest -ResponseHeadersVariable rh | Out-Null $url = $rh['OData-EntityId'] $selectedString = Select-String -InputObject $url -Pattern '(?<=\().*?(?=\))' return [System.Guid]::New($selectedString.Matches.Value.ToString()) } function Get-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id, [String] $query ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' + $query $getHeaders = $baseHeaders.Clone() $getHeaders.Add('If-None-Match', $null) $getHeaders.Add('Prefer', 'odata.include-annotations="*"') $RetrieveRequest = @{ Uri = $uri Method = 'Get' Headers = $getHeaders } Invoke-RestMethod @RetrieveRequest } function Update-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id, [Parameter(Mandatory)] [hashtable] $body ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' # Header for Update operations $updateHeaders = $baseHeaders.Clone() $updateHeaders.Add('Content-Type', 'application/json') $updateHeaders.Add('If-Match', '*') # Prevent Create $UpdateRequest = @{ Uri = $uri Method = 'Patch' Headers = $updateHeaders Body = ConvertTo-Json $body } Invoke-RestMethod @UpdateRequest } function Remove-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' $DeleteRequest = @{ Uri = $uri Method = 'Delete' Headers = $baseHeaders } Invoke-RestMethod @DeleteRequest }Para obtener información sobre cómo redactar estas solicitudes, consulte los artículos siguientes:
Guarde el archivo
TableOperations.ps1.Copie el código siguiente y péguelo en el
test.ps1archivo.. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 . $PSScriptRoot\TableOperations.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Retrieve Records Write-Host 'Retrieve first three account records:' (Get-Records ` -setName accounts ` -query '?$select=name&$top=3').value | Format-Table -Property name, accountid # Create a record Write-Host 'Create an account record:' $newAccountID = New-Record ` -setName accounts ` -body @{ name = 'Example Account'; accountcategorycode = 1 # Preferred } Write-Host "Account with ID $newAccountID created" # Retrieve a record Write-Host 'Retrieve the created record:' Get-Record ` -setName accounts ` -id $newAccountID.Guid '?$select=name,accountcategorycode' | Format-List -Property name, accountid, accountcategorycode, accountcategorycode@OData.Community.Display.V1.FormattedValue # Update a record Write-Host 'Update the record:' $updateAccountData = @{ name = 'Updated Example account'; accountcategorycode = 2; #Standard } Update-Record ` -setName accounts ` -id $newAccountID.Guid ` -body $updateAccountData Write-Host 'Retrieve the updated the record:' Get-Record ` -setName accounts ` -id $newAccountID.Guid ` -query '?$select=name,accountcategorycode' | Format-List -Property name, accountid, accountcategorycode, accountcategorycode@OData.Community.Display.V1.FormattedValue # Delete a record Write-Host 'Delete the record:' Remove-Record ` -setName accounts ` -id $newAccountID.Guid Write-Host "The account with ID $newAccountID was deleted"Recuerde cambiar el
https://yourorg.crm.dynamics.com/valor para que coincida con la dirección URL de su entorno.Para ejecutar el script, presione F5.
La salida podría ser similar a esta salida:
PS C:\scripts> . 'C:\scripts\test.ps1' Retrieve first three account records: name accountid ---- --------- Fourth Coffee (sample) d2382248-cd99-ee11-be37-000d3a9b7981 Litware, Inc. (sample) d4382248-cd99-ee11-be37-000d3a9b7981 Adventure Works (sample) d6382248-cd99-ee11-be37-000d3a9b7981 Create an account record: Account with ID a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 created Retrieve the created record: name : Example Account accountid : a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 accountcategorycode : 1 accountcategorycode@OData.Community.Display.V1.FormattedValue : Preferred Customer Update the record: Retrieve the updated the record: name : Updated Example account accountid : a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 accountcategorycode : 2 accountcategorycode@OData.Community.Display.V1.FormattedValue : Standard Delete the record: The account with ID a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 was deleted
Administrar excepciones
Hasta ahora, en este artículo ha copiado y pegado el código proporcionado. Pero cuando empiezas a escribir y usar tus propias funciones, puedes encontrar errores. Cuando se producen estos errores, pueden ser de Dataverse o del script.
Agregue una función auxiliar que pueda ayudar a detectar el origen de los errores y extraer los detalles pertinentes de los errores devueltos por Dataverse.
Agregue la siguiente
Invoke-DataverseCommandsfunción alCore.ps1archivo:function Invoke-DataverseCommands { param ( [Parameter(Mandatory)] $commands ) try { Invoke-Command $commands } catch [Microsoft.PowerShell.Commands.HttpResponseException] { Write-Host "An error occurred calling Dataverse:" -ForegroundColor Red $statuscode = [int]$_.Exception.StatusCode; $statusText = $_.Exception.StatusCode Write-Host "StatusCode: $statuscode ($statusText)" # Replaces escaped characters in the JSON [Regex]::Replace($_.ErrorDetails.Message, "\\[Uu]([0-9A-Fa-f]{4})", {[char]::ToString([Convert]::ToInt32($args[0].Groups[1].Value, 16))} ) } catch { Write-Host "An error occurred in the script:" -ForegroundColor Red $_ } }La
Invoke-DataverseCommandsfunción utiliza el cmdlet Invoke-Command para procesar un conjunto de comandos dentro de un bloque try/catch. Los errores devueltos por Dataverse son HttpResponseException errores; por lo tanto, el primer bloquecatchescribe un mensajeAn error occurred calling Dataverse:al terminal con los datos de error JSON.Los datos JSON en
$_.ErrorDetails.Messagecontienen algunos caracteres Unicode escapados. Por ejemplo:\u0026en lugar de&y\u0027en lugar de'. Esta función incluye código que reemplaza esos caracteres con caracteres sin escape para que coincidan exactamente con los errores que ve en otros lugares.De lo contrario, los errores se vuelven a escribir en la ventana del terminal con un mensaje:
An error occurred in the script:Guarde el archivo
Core.ps1.Edite el
test.ps1archivo para agregar el siguiente script que usa un valor de parámetro no válidosetName. Elaccountparámetro debe seraccounts. Este error es común.. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 . $PSScriptRoot\TableOperations.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change this Invoke-DataverseCommands { # Retrieve Records Write-Host 'Retrieve first three account records:' (Get-Records ` -setName account ` -query '?$select=name&$top=3').value | Format-Table -Property name, accountid }Recuerde cambiar el
https://yourorg.crm.dynamics.com/valor para que coincida con la dirección URL de su entorno.Para ejecutar el script, presione F5.
La salida podría ser similar a esta salida:
PS C:\scripts> . 'C:\scripts\test.ps1' Retrieve first three account records: An error occurred calling Dataverse: StatusCode: 404 (NotFound) { "error": { "code": "0x80060888", "message": "Resource not found for the segment 'account'." } }Edite el archivo
test.ps1para lanzar un error de script dentro del bloqueInvoke-DataverseCommands:Invoke-DataverseCommands { throw 'A script error' }Para ejecutar el script, presione F5.
La salida debe ser casi la misma que si no se incluyera en el
Invoke-DataverseCommandsbloque :PS C:\scripts> . 'C:\scripts\test.ps1' An error occurred in the script: Exception: C:\scripts\test.ps1:8:4 Line | 8 | throw 'A script error' | ~~~~~~~~~~~~~~~~~~~~~~ | A script error
Administración de límites de protección del servicio Dataverse
Los límites de la API de protección de Dataverse Service ayudan a garantizar que Dataverse proporciona una disponibilidad y un rendimiento coherentes. Cuando las aplicaciones cliente realizan demandas extraordinarias en los recursos del servidor mediante la API web, Dataverse devuelve errores 429 Demasiadas solicitudes y las aplicaciones cliente deben pausar las operaciones durante la duración especificada en el encabezado Retry-After.
El parámetro MaximumRetryCount del cmdlet de PowerShellInvoke-RestMethod especifica cuántas veces PowerShell reintenta una solicitud cuando se recibe un código de error entre 400 y 599, ambos incluidos o 304. Esto significa que PowerShell reintenta los errores de protección del servicio Dataverse 429 al incluir un valor para este parámetro. El MaximumRetryCount parámetro se puede usar con RetryIntervalSec para especificar el número de segundos que se van a esperar. El valor predeterminado es de 5 segundos. Si la respuesta de error incluye un Retry-After encabezado para un error 429, como hacen los errores de protección del servicio Dataverse, ese valor se usa en su lugar.
Es posible que nunca encuentre un error de límite de protección de servicio mientras aprende a usar la API web de Dataverse con PowerShell. Sin embargo, los scripts que escriba pueden enviar un gran número de solicitudes que producen errores, por lo que aprenderá a administrarlos mejor mediante PowerShell.
Si agrega el parámetro MaximumRetryCount a cada llamada de Dataverse mediante Invoke-RestMethod, PowerShell reintenta una amplia gama de errores. Volver a intentar cada error ralentiza los scripts, especialmente al desarrollar y probar. Tendría que esperar de 10 a 15 segundos cada vez que se produzca un error, en función del número de reintentos que especifique. Un enfoque alternativo consiste en encapsular el Invoke-RestMethod en su propio método que gestiona los reintentos para errores específicos.
La siguiente Invoke-ResilientRestMethod función toma un request objeto hashtable como parámetro obligatorio y una marca booleana returnHeader para indicar si se va a devolver o no el encabezado de respuesta. Cuando $returnHeader es verdadero, envía la solicitud utilizando el comando Invoke-RestMethod y el parámetro ResponseHeadersVariable para capturar los encabezados devueltos. La función usa Out-Null para que la salida que represente el cuerpo de respuesta vacío no se devuelva con la función . De lo contrario, la función envía la solicitud mediante Invoke-RestMethod con el objeto request y devuelve el cuerpo de la respuesta.
Si Invoke-RestMethod da un error 429, comprueba si el objeto request tiene una propiedad MaximumRetryCount. Si la función se ejecuta correctamente, crea una MaximumRetryCount propiedad establecida en 3. A continuación, se vuelve a intentar Invoke-RestMethod utilizando el objeto de solicitud y el valor del encabezado de respuesta Retry-After. Si la returnHeader marca es true, devuelve el encabezado de respuesta. Si Invoke-RestMethod falla con cualquier otro error, vuelve a lanzar la excepción.
function Invoke-ResilientRestMethod {
param (
[Parameter(Mandatory)]
$request,
[bool]
$returnHeader
)
try {
if ($returnHeader) {
Invoke-RestMethod @request -ResponseHeadersVariable rhv | Out-Null
return $rhv
}
Invoke-RestMethod @request
}
catch [Microsoft.PowerShell.Commands.HttpResponseException] {
$statuscode = $_.Exception.Response.StatusCode
# 429 errors only
if ($statuscode -eq 'TooManyRequests') {
if (!$request.ContainsKey('MaximumRetryCount')) {
$request.Add('MaximumRetryCount', 3)
# Don't need - RetryIntervalSec
# When the failure code is 429 and the response includes the Retry-After property in its headers,
# the cmdlet uses that value for the retry interval, even if RetryIntervalSec is specified
}
# Will attempt retry up to 3 times
if ($returnHeader) {
Invoke-RestMethod @request -ResponseHeadersVariable rhv | Out-Null
return $rhv
}
Invoke-RestMethod @request
}
else {
throw $_
}
}
catch {
throw $_
}
}
Puede usar una función similar en las funciones reutilizables. Cuando las funciones necesitan devolver valores del encabezado de la respuesta, deben establecer el valor returnHeader a $true. Por ejemplo, la función siguiente New-Record modifica la función de ejemplo en Crear funciones de operaciones de tabla para usarlas Invoke-ResilientRestMethod en lugar de Invoke-RestMethod directamente.
function New-Record {
param (
[Parameter(Mandatory)]
[String]
$setName,
[Parameter(Mandatory)]
[hashtable]
$body
)
$postHeaders = $baseHeaders.Clone()
$postHeaders.Add('Content-Type', 'application/json')
$CreateRequest = @{
Uri = $baseURI + $setName
Method = 'Post'
Headers = $postHeaders
Body = ConvertTo-Json $body
}
# Before:
# Invoke-RestMethod @CreateRequest -ResponseHeadersVariable rh | Out-Null
# After:
$rh = Invoke-ResilientRestMethod -request $CreateRequest -returnHeader $true
$url = $rh['OData-EntityId']
$selectedString = Select-String -InputObject $url -Pattern '(?<=\().*?(?=\))'
return [System.Guid]::New($selectedString.Matches.Value.ToString())
}
De lo contrario, Invoke-ResilientRestMethod puede reemplazar el Invoke-RestMethod, como se muestra en este Get-Record ejemplo.
function Get-Record {
param (
[Parameter(Mandatory)]
[String]
$setName,
[Parameter(Mandatory)]
[Guid]
$id,
[String]
$query
)
$uri = $baseURI + $setName
$uri = $uri + '(' + $id.Guid + ')' + $query
$getHeaders = $baseHeaders.Clone()
$getHeaders.Add('If-None-Match', $null)
$getHeaders.Add('Prefer', 'odata.include-annotations="*"')
$RetrieveRequest = @{
Uri = $uri
Method = 'Get'
Headers = $getHeaders
}
# Before:
# Invoke-RestMethod @RetrieveRequest
# After:
Invoke-ResilientRestMethod $RetrieveRequest
}
La única diferencia es que pasa la tabla hash ($RetrieveRequest) al método en lugar de usar splatting (@RetrieveRequest). De lo contrario, recibirá un error de script: A parameter cannot be found that matches parameter name 'Headers'.
Corregir errores usando Fiddler
Fiddler es un proxy de depuración web que se usa para ver el tráfico HTTP en el equipo. Visualizar estos datos es útil al depurar scripts. De forma predeterminada, las solicitudes HTTP y las respuestas enviadas mediante Invoke-RestMethod cmdlet no son visibles cuando se usa Fiddler.
Para ver el tráfico HTTP en Fiddler, establezca el Invoke-RestMethodparámetro Proxy en la dirección URL configurada como proxy de Fiddler en el equipo local. De forma predeterminada, la dirección URL es http://127.0.0.1:8888. La dirección URL puede ser diferente.
Por ejemplo, si invoca la función WhoAmI con el -Proxy parámetro establecido mientras Fiddler captura el tráfico:
Invoke-RestMethod `
-Uri ($environmentUrl + 'api/data/v9.2/WhoAmI') `
-Method Get `
-Headers $baseHeaders `
-Proxy 'http://127.0.0.1:8888'
En Fiddler, puede ver todos los detalles:
GET https://yourorg.api.crm.dynamics.com/api/data/v9.2/WhoAmI HTTP/1.1
Host: yourorg.api.crm.dynamics.com
OData-MaxVersion: 4.0
Accept: application/json
Authorization: Bearer [REDACTED]
OData-Version: 4.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.22631; en-US) PowerShell/7.4.0
Accept-Encoding: gzip, deflate, br
HTTP/1.1 200 OK
Cache-Control: no-cache
Allow: OPTIONS,GET,HEAD,POST
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Vary: Accept-Encoding
x-ms-service-request-id: 7341c0c1-3343-430b-98ea-292567ed4776
Set-Cookie: ARRAffinity=f60cbee43b7af0a5f322e7ce57a018546ed978f67f0c11cbb5e15b02ddb091a915134d20c556b0b34b9b6ae43ec3f5dcdad61788de889ffc592af7aca85fc1c508DC0FC94CB062A12107345846; path=/; secure; HttpOnly
Set-Cookie: ReqClientId=4fc95009-0b3d-4a19-b223-0d80745636ac; expires=Sun, 07-Jan-2074 21:10:42 GMT; path=/; secure; HttpOnly
Set-Cookie: orgId=00aa00aa-bb11-cc22-dd33-44ee44ee44ee; expires=Sun, 07-Jan-2074 21:10:42 GMT; path=/; secure; HttpOnly
x-ms-service-request-id: 1ee13aa7-47f3-4a75-95fa-2916775a1f79
Strict-Transport-Security: max-age=31536000; includeSubDomains
REQ_ID: 1ee13aa7-47f3-4a75-95fa-2916775a1f79
CRM.ServiceId: framework
AuthActivityId: 0b562cc3-56f6-44f0-a26e-4039cfc4be6a
x-ms-dop-hint: 48
x-ms-ratelimit-time-remaining-xrm-requests: 1,200.00
x-ms-ratelimit-burst-remaining-xrm-requests: 5999
OData-Version: 4.0
X-Source: 110212218438874147222728177124203420477168182861012399121919014511175711948418152
Public: OPTIONS,GET,HEAD,POST
Set-Cookie: ARRAffinity=f60cbee43b7af0a5f322e7ce57a018546ed978f67f0c11cbb5e15b02ddb091a915134d20c556b0b34b9b6ae43ec3f5dcdad61788de889ffc592af7aca85fc1c508DC0FC94CB062A12107345846; path=/; secure; HttpOnly
X-Source: 2302101791355821068628523819830862152291172232072372448021147103846182145238216119
Date: Sun, 07 Jan 2024 21:10:42 GMT
Content-Length: 277
{"@odata.context":"https://yourorg.api.crm.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse","BusinessUnitId":"11bb11bb-cc22-dd33-ee44-55ff55ff55ff","UserId":"22cc22cc-dd33-ee44-ff55-66aa66aa66aa","OrganizationId":"00aa00aa-bb11-cc22-dd33-44ee44ee44ee"}
Si Fiddler no se está ejecutando, obtendrá un error:
Invoke-RestMethod: C:\scripts\test.ps1:8:1
Line |
8 | Invoke-RestMethod `
| ~~~~~~~~~~~~~~~~~~~
| No connection could be made because the target machine actively refused it.
Si decide enrutar todas las Invoke-RestMethod llamadas a través de una sola función, como la Invoke-ResilientRestMethod descrita en Administración de límites de protección del servicio Dataverse, puede establecer algunas variables en el Core.ps1 archivo para configurar esta opción en una sola ubicación.
# Set to true only while debugging with Fiddler
$debug = $true
# Set this value to the Fiddler proxy URL configured on your computer
$proxyUrl = 'http://127.0.0.1:8888'
Dentro de su función centralizada, puede establecer el parámetro -Proxy con propagación y utilizar la tabla hash $request solo al realizar al depurar con Fiddler.
function Invoke-ResilientRestMethod {
param (
[Parameter(Mandatory)]
$request,
[bool]
$returnHeader
)
if ($debug) {
$request.Add('Proxy', $proxyUrl)
}
...
Más información sobre la captura del tráfico web con Fiddler
Descarga el documento $metadata CSDL de la API web de Dataverse.
Common Schema Definition Language (CSDL) $metadata es la fuente de información definitiva sobre las funcionalidades de la API web de Dataverse. Puede verlo en un explorador, pero es posible que le resulte más fácil descargar el archivo y verlo en Visual Studio Code. El siguiente script es una versión modificada del script introducido en Quick Start Web API con PowerShell. La diferencia es que usa el cmdletInvoke-WebRequest, que es más adecuado para descargar un documento XML.
$environmentUrl = 'https://yourorg.crm.dynamics.com/' # change to your organization
$writeFileTo = 'C:\temp\yourorg.xml' # change to your organization
## Login if not already logged in
if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) {
Connect-AzAccount | Out-Null
}
# Get an access token
$secureToken = (Get-AzAccessToken `
-ResourceUrl $environmentUrl `
-AsSecureString).Token
# Convert the secure token to a string
$token = ConvertFrom-SecureString `
-SecureString $secureToken `
-AsPlainText
# Common headers
$xmlHeaders = @{
'Authorization' = 'Bearer ' + $token
'Accept' = 'application/xml'
'OData-MaxVersion' = '4.0'
'OData-Version' = '4.0'
}
$doc = [xml](Invoke-WebRequest `
-Uri ($environmentUrl + 'api/data/v9.2/$metadata?annotations=true') `
-Method 'Get' `
-Headers $xmlHeaders ).Content
$StringWriter = New-Object System.IO.StringWriter
$XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter
$xmlWriter.Formatting = 'indented'
$xmlWriter.Indentation = 2
$doc.WriteContentTo($XmlWriter)
$XmlWriter.Flush()
$StringWriter.Flush()
Set-Content -Path $writeFileTo -Value $StringWriter.ToString()
code $writeFileTo
- Copie el script.
- Edite las
$environmentUrlvariables y$writeFileTopara que coincidan con sus necesidades. - Ejecute el script en Visual Studio Code.
El documento de $metadata CSDL de Dataverse Web API se abre en Visual Studio Code.
Puede recibir una notificación diciendo: Por motivos de rendimiento, los símbolos de documento están limitados a 5000 elementos. Si se establece un nuevo límite, cierre y vuelva a abrir este archivo para volver a calcular los símbolos del documento.
La notificación ofrece la opción de cambiar el límite de extensión xml.symbols.maxItemsComputed XML de Visual Studio Code. Para la mayoría de los documentos CSDL de $metadata de Dataverse Web API, establecer el límite en 500000 debería ser suficiente.
Solución de problemas
Esta sección contiene algunas instrucciones para los problemas que puede encontrar.
Cuadro de diálogo de error: conecte ENOENT\\.\pipe\<RANDOM_text> con el botón Abrir "launch.json"
Este error puede producirse al depurar con Visual Studio Code. Para resolver el error:
- Seleccione Ver>paleta de comandos... en el menú de Visual Studio Code o presione Ctrl+Mayús+P.
- Escriba
restarty seleccionePowershell: Restart session. Consulte El problema 4332 de GitHub de PowerShell/vscode-powershell para obtener más información.
Pasos siguientes
Obtenga más información sobre las funcionalidades de api web de Dataverse mediante la comprensión de los documentos del servicio.
Revise y ejecute código de ejemplo.