Вопрос

Я работаю над серией сценариев Powershell, которые моя компания будет использовать для передачи данных на Box.com и обратно.Единственное, чего я не могу понять, так это загрузки файлов.API Box требует многочастной операции POST для загрузки, и я видел несколько ответов здесь на SO, указывающих, что я должен иметь возможность сделать это в Powershell (например, Вот этот).Но я не могу заставить его работать.

Вот код, который у меня есть сейчас:

Function Post-File {
    Param(
            [Parameter(Mandatory=$True,Position=1)]
            [string]$SourcePath,
            [Parameter(Mandatory=$False,Position=2)]            
            [string]$FolderId = ############
    )

    #Variables for building URIs
    $baseUrl = "https://upload.box.com/api/2.0/files/content"

    #Set Authorization for API requests
    $headers = @{}
    $AccessToken = Refresh-Tokens #A reference to another function that definitely works
    $headers.Add("Authorization", "Bearer $AccessToken")

    #Set POST content
    $body = @{}
    $body.Add("filename",  [IO.File]::ReadAllBytes($SourcePath))
    $body.Add("parent_id", $FolderId)

    #Upload the file
    Invoke-RestMethod -Uri $baseUrl -Method Post -Headers $headers -ContentType "multipart/form-data" -Body $body
}

Вот ответ, который я получаю:

{
 "type":"error",
 "status":400,
 "code":"invalid_request_parameters",
 "help_url":"http://developers.box.com/docs/#errors",
 "message":"Invalid input parameters in request",
 "request_id":"1764475572534bcddfe04b7"
}

Я также попробовал пару других перестановок, которые не работают.Я пробовал использовать -InFile включить Invoke-RestMethod вместо -Body.Я также пробовал использовать Get-Content -Raw на месте [IO.File]::ReadAllBytes.Оба они возвращают более общую ошибку: The server encountered an internal error or misconfiguration and was unable to complete your request..

Я почти уверен, что это как-то связано с моим filename параметр неверен, но я не знаю, как это исправить.Согласно API коробки, вот как это должно выглядеть в Curl.Может ли кто-нибудь помочь мне правильно перевести это для Powershell?

https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F filename=@FILE_NAME \
-F parent_id=PARENT_FOLDER_ID
Это было полезно?

Решение

Есть пара вещей, которые усложняют эту задачу в PowerShell:

  1. А filename Параметр указывает имя файла, а не его содержимое.
  2. Тело запроса необходимо для указания имени файла и места назначения.
  3. PowerShell лечит -InFile и -Body аргументы как взаимоисключающие.
  4. PowerShell, по-видимому, не поддерживает изначально multipart/form-data POST, согласно вопрос на что вы ссылались.

Поскольку требуется тело запроса (1,2) - и, следовательно, -InFile невозможно использовать (3) – думаю, вам, возможно, придется свернуть свой собственный multipart/form-data тело (4), содержащее необходимые метаданные и содержимое файла. Этот пост в блоге описывает способ сделать это.Содержимое там — короткая строка (твит), но принцип тот же.

Ниже приведена трассировка Fiddler только что выполненной загрузки с использованием Box Windows SDK.Это показывает, как должен выглядеть запрос при передаче по сети.А $BOUNDARY — это произвольная уникальная строка — GUID отлично работает.

POST https://upload.box.com/api/2.0/files/content HTTP/1.1
Authorization: Bearer $TOKEN
Content-Type: multipart/form-data; boundary="$BOUNDARY"
Host: upload.box.com
Content-Length: 2118
Accept-Encoding: gzip, deflate

--$BOUNDARY

Content-Disposition: form-data; name="file"; filename="$FILENAME"

<THE CONTENT OF $FILENAME>    

--$BOUNDARY

Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="metadata"

{"parent":{"id":"$PARENT_FOLDER_ID"},"name":"$FILENAME"}

--$BOUNDARY--

Вот ответ, который я получил:

HTTP/1.1 201 Created
Date: Mon, 14 Apr 2014 12:52:33 GMT
Server: Apache
Cache-Control: no-cache, no-store
Content-Length: 364
Connection: close
Content-Type: application/json

{"total_count":1,"entries":[{"type":"file","id":"$ID","name":"$FILENAME", ... }]}

Другие советы

Возможно, я прозвучу глупо, но что произойдет, если вы это сделаете?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top