Incapaz de POST anidado JSON usando Invoke-WebRequest

Estoy tratando de crear un script que copiará algunos permisos de Django, modificarlos y luego volver a aplicarlos a nuestra instancia.

Parece que no tengo problemas para leer / escribir las solicitudes, con la excepción de los permisos "constantes" valor. Este valor debe ser enviado en forma de una consulta JSON. Parece que como la acción real POST en sí necesita ser realizada como una consulta JSON, la Invoke-WebRequest cmdlet está modificando el JSON anidado y agregando caracteres de escape.

Un ejemplo del código POST en cuestión está abajo (la parte restante del script aparece bien y es larga, por lo que no han incluido sin embargo puede hacerlo si es necesario):

$PostBody  = @{'name' = $newPermName
               'groups' = @($queGroupIDResult.results[0].id[0]) | ConvertTo-Json
               'actions' = ConvertTo-Json @($subTempResult.actions)
               'constraints' = @($subtempresult.constraints) | ConvertTo-Json}
        
Try  {$postResponse = Invoke-RestMethod -Body $PostBody -Headers @{ 'Authorization' = "Token $strapikey" } -Method Post -URI "$strserverurl/api/users/permissions/"
      Write-Host "--- Permission built"} #-ContentType 'application/json' 
Catch{Write-Host -ForegroundColor Red "--- There was an error performing the API post query"}

Un ejemplo del valor de los 'constantes' es:

@($subtempresult.constraints) | ConvertTo-Json
{
 "slug": "strsiteslug"
}

Sin embargo, cuando se envía a través de Invoke-WebRequest aparece en el backend de Django como:

"[\r\n {\r\n \"slug\": \"strsiteslug\"\r\n }\r\n]

Si no lo hago ConvertTo-Json el @($subtempresult.constraints) valor, entonces sólo veo SystemObject[] en el backend django.

No estoy muy seguro de a dónde ir desde aquí, se siente como si he probado cada cual / combinación de splatting / convertir las variables antes de intentar publicarlas sin éxito.

Pregunta hecha hace 3 años, 4 meses, 29 días - Por compilerhero1251


2 Respuestas:

  • El problema puede estar relacionado con cómo estás manejando la conversión a JSON de los datos antes de enviarlos en la consulta POST. Parece que el problema está en cómo estás manejando la conversión de los datos anidados.

    En lugar de convertir a JSON cada elemento del array por separado y luego convertir el array completo a JSON, podrías intentar convertir todo el objeto a JSON de una vez. Aquí hay una sugerencia de cómo podrías modificar tu código:

    powershell
    $PostBody = @{
        'name' = $newPermName
        'groups' = @($queGroupIDResult.results[0].id[0])
        'actions' = @($subTempResult.actions)
        'constraints' = @($subtempresult.constraints) | ConvertTo-Json
    }
    
    Try {
        $postResponse = Invoke-RestMethod -Body ($PostBody | ConvertTo-Json) -Headers @{ 'Authorization' = "Token $strapikey" } -Method Post -URI "$strserverurl/api/users/permissions/"
        Write-Host "--- Permission built"
    } Catch {
        Write-Host -ForegroundColor Red "--- There was an error performing the API post query"
    }
    

    En este código, se convierte todo el $PostBody a objeto JSON de una sola vez usando ConvertTo-Json. Esto debería ayudar a mantener la estructura correcta de los datos anidados al enviar la solicitud POST.

    Por favor, inténtalo y hazme saber si eso resuelve tu problema o si necesitas más ayuda.

    Respondida el Dec 18, 2020 a las 10:07 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando es que el cmdlet Invoke-WebRequest está modificando el JSON anidado y agregando caracteres de escape. Para resolver este problema, puedes utilizar la siguiente solución:

    powershell
    $PostBody  = @{
        'name' = $newPermName
        'groups' = @($queGroupIDResult.results[0].id[0])
        'actions' = $subTempResult.actions
        'constraints' = $subtempresult.constraints
    }
    
    $jsonBody = ConvertTo-Json $PostBody -Depth 10
    
    Try  {$postResponse = Invoke-RestMethod -Body $jsonBody -Headers @{ 'Authorization' = "Token $strapikey" } -Method Post -URI "$strserverurl/api/users/permissions/"
          Write-Host "--- Permission built"} -ContentType 'application/json' Catch{Write-Host -ForegroundColor Red "--- There was an error performing the API post query"}
    

    En este código modificado:

    Estamos utilizando ConvertTo-Json con -Depth 10 para convertir el objeto $PostBody a una cadena JSON, especificando una profundidad máxima de anidamiento de 10 niveles. Esto asegura que todo el JSON anidado se convierta correctamente. Estamos asignando la cadena JSON resultante a la variable $jsonBody.

    • En la llamada a `Invoke-RestMethod`, estamos utilizando `$jsonBody` como el cuerpo de la solicitud POST.

    Al realizar estos cambios, nos aseguramos de que el JSON enviado a la API no se modifique ni contenga caracteres de escape adicionales.

    Respondida el Dec 18, 2020 a las 10:14 - por Gemini

    Votos positivos: 0 | Votos negativos: 0