I'm trying to send a file via Invoke-RestMethod in a similar context as curl with the -F switch.
我正在尝试通过Invoke-RestMethod在类似的上下文中使用-F开关发送文件。
Curl Example
卷曲示例
curl -F FileName=@"/path-to-file.name" "https://uri-to-post"
In powershell, I've tried something like this:
在powershell中,我尝试过这样的事情:
$uri = "https://uri-to-post"
$contentType = "multipart/form-data"
$body = @{
"FileName" = Get-Content($filePath) -Raw
}
Invoke-WebRequest -Uri $uri -Method Post -ContentType $contentType -Body $body
}
If I check fiddler I see that the body contains the raw binary data, but I get a 200 response back showing no payload has been sent.
如果我检查fiddler,我看到正文包含原始二进制数据,但我得到200响应,显示没有发送有效负载。
I've also tried to use the -InFile parameter with no luck.
我也尝试过使用-InFile参数而没有运气。
I've seen a number of examples using a .net class, but was trying to keep this simple with the newer Powershell 3 commands.
我已经看过许多使用.net类的例子,但是他们试图用更新的Powershell 3命令来保持这个简单。
Does anyone have any guidance or experience making this work?
有没有人有任何指导或经验使这项工作?
3 个解决方案
#1
10
The problem here was what the API required some additional parameters. Initial request required some parameters to accept raw content and specify filename/size. After setting that and getting back proper link to submit, I was able to use:
这里的问题是API需要一些额外的参数。初始请求需要一些参数来接受原始内容并指定文件名/大小。在设置并返回正确的提交链接后,我能够使用:
Invoke-RestMethod -Uri $uri -Method Post -InFile $filePath -ContentType "multipart/form-data"
#2
4
The accepted answer won't do a multipart/form-data
request, but rather a application/x-www-form-urlencoded
request forcing the Content-Type
header to a value that the body does not contain.
接受的答案不会执行multipart / form-data请求,而是应用/ x-www-form-urlencoded请求将Content-Type标头强制为正文不包含的值。
One way to send a multipart/form-data
formatted request with PowerShell is:
使用PowerShell发送multipart / form-data格式化请求的一种方法是:
$ErrorActionPreference = 'Stop'
$fieldName = 'file'
$filePath = 'C:\Temp\test.pdf'
$url = 'http://posttestserver.com/post.php'
Try {
Add-Type -AssemblyName 'System.Net.Http'
$client = New-Object System.Net.Http.HttpClient
$content = New-Object System.Net.Http.MultipartFormDataContent
$fileStream = [System.IO.File]::OpenRead($filePath)
$fileName = [System.IO.Path]::GetFileName($filePath)
$fileContent = New-Object System.Net.Http.StreamContent($fileStream)
$content.Add($fileContent, $fieldName, $fileName)
$result = $client.PostAsync($url, $content).Result
$result.EnsureSuccessStatusCode()
}
Catch {
Write-Error $_
exit 1
}
Finally {
if ($client -ne $null) { $client.Dispose() }
if ($content -ne $null) { $content.Dispose() }
if ($fileStream -ne $null) { $fileStream.Dispose() }
if ($fileContent -ne $null) { $fileContent.Dispose() }
}
#3
1
I found this post and changed it a bit
我发现这篇文章并稍微改了一下
$fileName = "..."
$uri = "..."
$currentPath = Convert-Path .
$filePath="$currentPath\$fileName"
$fileBin = [System.IO.File]::ReadAlltext($filePath)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"file`"; filename=`"$fileName`"",
"Content-Type: application/octet-stream$LF",
$fileBin,
"--$boundary--$LF"
) -join $LF
Invoke-RestMethod -Uri $uri -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines
#1
10
The problem here was what the API required some additional parameters. Initial request required some parameters to accept raw content and specify filename/size. After setting that and getting back proper link to submit, I was able to use:
这里的问题是API需要一些额外的参数。初始请求需要一些参数来接受原始内容并指定文件名/大小。在设置并返回正确的提交链接后,我能够使用:
Invoke-RestMethod -Uri $uri -Method Post -InFile $filePath -ContentType "multipart/form-data"
#2
4
The accepted answer won't do a multipart/form-data
request, but rather a application/x-www-form-urlencoded
request forcing the Content-Type
header to a value that the body does not contain.
接受的答案不会执行multipart / form-data请求,而是应用/ x-www-form-urlencoded请求将Content-Type标头强制为正文不包含的值。
One way to send a multipart/form-data
formatted request with PowerShell is:
使用PowerShell发送multipart / form-data格式化请求的一种方法是:
$ErrorActionPreference = 'Stop'
$fieldName = 'file'
$filePath = 'C:\Temp\test.pdf'
$url = 'http://posttestserver.com/post.php'
Try {
Add-Type -AssemblyName 'System.Net.Http'
$client = New-Object System.Net.Http.HttpClient
$content = New-Object System.Net.Http.MultipartFormDataContent
$fileStream = [System.IO.File]::OpenRead($filePath)
$fileName = [System.IO.Path]::GetFileName($filePath)
$fileContent = New-Object System.Net.Http.StreamContent($fileStream)
$content.Add($fileContent, $fieldName, $fileName)
$result = $client.PostAsync($url, $content).Result
$result.EnsureSuccessStatusCode()
}
Catch {
Write-Error $_
exit 1
}
Finally {
if ($client -ne $null) { $client.Dispose() }
if ($content -ne $null) { $content.Dispose() }
if ($fileStream -ne $null) { $fileStream.Dispose() }
if ($fileContent -ne $null) { $fileContent.Dispose() }
}
#3
1
I found this post and changed it a bit
我发现这篇文章并稍微改了一下
$fileName = "..."
$uri = "..."
$currentPath = Convert-Path .
$filePath="$currentPath\$fileName"
$fileBin = [System.IO.File]::ReadAlltext($filePath)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"file`"; filename=`"$fileName`"",
"Content-Type: application/octet-stream$LF",
$fileBin,
"--$boundary--$LF"
) -join $LF
Invoke-RestMethod -Uri $uri -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines