Post file to Web Api via PowerShell

2019-07-12 18:28发布

I have a Web Api endpoint that I am currently using to upload a file. Below is the relevant snippet of C#:

var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider); // Exception thrown here

foreach (var file in provider.Contents)
{
    var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
    var buffer = await file.ReadAsByteArrayAsync();
    // Doing stuff with the file here
}

The above works fine when I test via Postman (chrome extension). I am not using a Content-Type header when I do this. The body is form-data and the only input is an attached file.

I am now trying to make this same request via PowerShell and am struggling (it should be known that I am new to both Web Api and PowerShell). Below is the powershell script I am running:

$apiKey=$args[0]
Write-Host "Using API Key: $apiKey"
$fileId=$args[1]
Write-Host "Using File ID: $fileId"
$sourceFile=$args[2]
Write-Host "Using File: $sourceFile"

$baseUrl = "http://localhost:23857/api"
$url = "$baseUrl/file/$fileId/version"

$fileBin = [IO.File]::ReadAllBytes($sourceFile)
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$fileEnc = $enc.GetString($fileBin)
$boundary = [System.Guid]::NewGuid().ToString()

$LF = "`n"
$bodyLines = (
    "--$boundary",
    "Content-Disposition: form-data; name=`"file`"; filename=`"TestApp.apk`"",
    "Content-Type: application/octet-stream$LF",
$fileEnc,
    "--$boundary--$LF"
) -join $LF

try {
    Invoke-RestMethod -Uri $url -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -TimeoutSec 120 -Body $bodyLines -Headers @{"ApiKey"=$apiKey}
}
catch [System.Net.WebException] {
    Write-Error( "FAILED to reach '$URL': $_" )
    throw $_
}

The URL is hit successfully, however an exception is thrown on the line await Request.Content.ReadAsMultipartAsync(provider);. The exception message is:

Unexpected end of MIME multipart stream. MIME multipart message is not complete.

Any ideas as to the problem?

Edit 1

I have used the following C# code to look at the request content once the endpoint has been reached:

byte[] rawByteArray = await Request.Content.ReadAsByteArrayAsync();
String rawString = System.Text.Encoding.UTF8.GetString(rawByteArray);

Output from (successful) postman request:

------WebKitFormBoundaryBlYhYzAJUyRbTShB
Content-Disposition: form-data; name="file"; filename="TestApp.apk"
Content-Type: application/octet-stream

encoded file data here

Output from (failed) powershell request:

--f83e62e1-83a7-495c-8152-10d38500da41
Content-Disposition: form-data; name="file"; filename="TestApp.apk"
Content-Type: application/octet-stream

encoded file data here

Apart from the boundary delimiter, I can't see any difference here.

Edit 2

Still haven't found a solution. I heard that sometimes this exception is thrown if the request does not end in a new line. I appended this to the body (both client side and server side) and no change.

Can anyone see a problem with my approach?

0条回答
登录 后发表回答