Rest Powershell脚本使用多部分/表单数据调用HTTP POST时出现问题

Rest Powershell脚本使用多部分/表单数据调用HTTP POST时出现问题,rest,powershell,multipartform-data,Rest,Powershell,Multipartform Data,我正在开发一个powershell脚本,该脚本应该使用HTTPPOST方法调用RESTAPI。RESTAPI用于从外部备份文件还原特定于应用程序的备份资源。表单数据中备份文件的键名必须为“backupFile”。 内容类型为多部分/表单数据。以下是我正在做的: function invoke-rest { param([string]$uri) [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$tr

我正在开发一个powershell脚本,该脚本应该使用HTTPPOST方法调用RESTAPI。RESTAPI用于从外部备份文件还原特定于应用程序的备份资源。表单数据中备份文件的键名必须为“backupFile”。 内容类型为多部分/表单数据。以下是我正在做的:

function invoke-rest {
param([string]$uri)
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
#$enc = [system.Text.Encoding]::UTF8
$request = [System.Net.HttpWebRequest]::Create($uri)
$request.Credentials = New-Object system.net.networkcredential("user","password")
$request.CookieContainer = New-Object System.Net.CookieContainer
$request.AllowWriteStreamBuffering = $true;
$boundary = "--------------"+(get-date -format yyyymmddhhmmss).ToString()
$header = "--"+$boundary
$body = $header + "`r`n" +"Content-Disposition: form-data; name='backupFile'; filename='somefile.sql.gz'"+"`r`n" + "Content-Type: multipart/form-data"+"`r`n`r`n"

$body = $body + [System.Text.Encoding]::UTF8.GetString($(Get-Content 'somefile.sql.gz' -Encoding byte)) + "`r`n"
$footer = $header+"--"
$body = $body + $footer

$bytes = [System.Text.Encoding]::UTF8.GetBytes($body)
$request.ContentType = "multipart/form-data; boundary="+$boundary
$request.Method = "Post"
$request.keepAlive = $true
$request.ContentLength = $bytes.Length

$requestStream = $request.GetRequestStream()
$requestStream.Write($bytes,0,$bytes.length);
$requestStream.Flush();
$requestStream.Close();

$response = $request.GetResponse()
$responseStream = $response.GetResponseStream()
$stream = new-object System.IO.StreamReader $responseStream
$xmlDump = $stream.ReadToEnd()
$output = [xml]$xmlDump
$response.close()
return $output
}
$uri = "http://localhost/rest/backups"
invoke-rest $uri
引发的错误:REST请求失败,必须存在名为backupFile的数据表单,返回:Bad request(400)


我在这里做错了什么?

在这个场景中,400可能意味着在生成

文件是您在请求时需要提交的唯一参数吗?如果是这样,您可以使用WebClient.UploadFile API,让它处理生成大量请求的过程

$client = New-Object System.Net.WebClient
$client.Credentials = $creds
$client.UploadFile('http://localhost/rest/backups', 'c:\temp\somefile.sql.gz')
如果您确实需要在mime多部分请求中提交多个参数,那么您将面临一个痛苦的世界。我自己也必须通过powershell完成这项工作,这一点都不好玩,尤其是当您开始涉及二进制数据时。在经历了许多挫折和挫折之后,我最终完成了以下工作:转换一个值的哈希表并输出一个多部分。很抱歉,我无法准确地发现代码中的错误,但这可能会直接对您起作用,或者引导您确定问题所在

function ConvertTo-MimeMultiPartBody
{
    param(
        [Parameter(Mandatory=$true)]
        [string]$Boundary,
        [Parameter(Mandatory=$true)]
        [hashtable]$Data
    )

    $body = '';

    $Data.GetEnumerator() |% {
        $name = $_.Key
        $value = $_.Value

        $body += "--$Boundary`r`n"
        $body += "Content-Disposition: form-data; name=`"$name`""
        if ($value -is [byte[]]) {
            $fileName = $Data['FileName']
            if(!$fileName) {
                $fileName = $name
            }
            $body += "; filename=`"$fileName`"`r`n"
            $body += 'Content-Type: application/octet-stream'
            #ISO-8859-1 is only encoding where byte value == code point value
            $value = [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetString($value)
        }
        $body += "`r`n`r`n"
        $body += $value
        $body += "`r`n"
    }
    $body += "--$boundary--"
    return $body
}

我对你没有答案,但是除非这个代码必须在PuthS壳2上运行,否则你应该考虑使用<代码>调用REST方法< /> >:这类事情很难帮助。我的一般建议是从(它是免费的)中抓取Fiddler,并使用它来观察脚本和工作的东西(curl、交互式表单提交等)之间的差异。了解成功请求和失败请求之间的区别通常足以让您渡过难关。briantist,不幸的是,这必须在powershell 2.0中。keith hill,我现在缩小了范围。问题要么在于对sql.gz文件进行编码,要么在于我提供内容类型或内容编码头的方式。“请求正文”的内容类型应为application/x-gzip或application/octet流,“请求头”的内容类型应为“multipart/form data”。您认为我指定内容类型或编码内容类型的方式有问题吗?当我将内容类型与fiddler的请求主体进行比较时,它看起来很好。但我不知道我如何才能找出编码部分!