我在 .net core 3.1 中有一个 REST API 端点,如下所示:
[Route("Install")]
[HttpPost]
[RequestSizeLimit(524288000)]
public async Task<IActionResult> AddInstallFile(List<IFormFile> files)
我可以通过以下命令使用 cURL 上传文件:
curl -X POST MYURL Content-Type: multipart/form-data" -F "[email protected];type=application/x-zip-compressed"
它也可以通过 swagger 工作
在 powershell 中,虽然 Multipart/form-data 本身不支持,所以我使用以下代码上传到那里(本质上我使用了 chrome 开发工具中的“复制为 Powershell”功能的工作 swagger 上传来创建此代码):
$fileBytes = [System.IO.File]::ReadAllBytes("C:\Temp\filename.zip");
$enc = [System.Text.Encoding]::GetEncoding('utf-8')
$fileEnc = $enc.GetString($fileBytes)
Invoke-WebRequest -Uri "MYURL" `
-Method "POST" `
-Headers @{
"method"="POST"
"accept"="application/octet-stream"
"accept-encoding"="gzip, deflate, br"
} `
-ContentType "multipart/form-data; boundary=----WebKitFormBoundaryT2XycANuthCIUwGk" `
-Body ([System.Text.Encoding]::UTF8.GetBytes("------WebKitFormBoundaryT2XycANuthCIUwGk$([char]13)$([char]10)Content-Disposition: form-data; name=`"files`"; filename=`"filename.zip`"$([char]13)$([char]10)Content-Type: application/x-zip-compressed$([char]13)$([char]10)$([char]13)$([char]10)$fileEnc$([char]13)$([char]10)------WebKitFormBoundaryT2XycANuthCIUwGk--$([char]13)$([char]10)"))
此 Powershell 代码对于我拥有的小于 2MB 的 zip 文件工作正常,但对于另一个超过 80MB 的 zip 文件则失败
服务器上的错误在这里:
An unhandled exception has occurred while executing the request.
Exception:
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Sum[TSource](IEnumerable`1 source, Func`2 selector)
at netproject.ControllerClass.AddInstallFile(List`1 files) in ControllerClass.cs:line 44
本质上,当从 powershell 调用超过 50MB 的文件时,files 变量将显示为 null。 我尝试了 Invoke-WebRequest 和 Invoke-RestMethod ,结果相同
对于将来遇到此问题的任何人 - 如果您在 powershell 中获得有效的解决方案,我仍然有兴趣了解它。为了暂时解决这个问题,我使用 .net 框架来上传文件。代码在这里:
Write-Host "Uploading $name"
$url = "URL_TO_UPLOAD"
$file = "FULL_PATH_ZIP_FILE"
$fs = [System.IO.FileStream]::New($file, [System.IO.FileMode]::Open)
$f1 = New-Object System.Net.Http.StreamContent $fs
$client = New-Object System.Net.Http.HttpClient
$client.DefaultRequestHeaders.ConnectionClose = $true
$client.DefaultRequestHeaders.Add("Authorization", $auth);
$form = New-Object System.Net.Http.MultipartFormDataContent
$form.Add($f1, 'files', $name)
$rsp = $client.PostAsync($url, $form).Result
Write-Host "Upload status: " + $rsp.StatusCode
$fs.Close();
$fs.Dispose()
这种方法对我有用(假设您已经通过
-SessionVariable
存储的会话进行了身份验证):
$ImagePath = "C:\test.jpg"
# extract the image file name, without path
$fileName = Split-Path $imagePath -Leaf
# grab the raw bytes composing the image file
$imageBytes = [Io.File]::ReadAllBytes($imagePath)
$fileEnc = [System.Text.ASCIIEncoding]::GetEncoding('UTF-8').GetString($imageBytes);
#Set random boundary string for header
$boundary = [guid]::NewGuid().ToString()
$LF = "`r`n";
$bodyLines = (
"--$boundary",
"Content-Disposition: form-data; name=`"fileSize`"$LF",
"$($imageBytes.Length)",
"--$boundary",
"Content-Disposition: form-data; name=`"file`"; filename=`"$($fileName)`"",
"Content-Type: image/jpeg$LF",
$fileEnc,
"--$boundary--$LF"
) -join $LF
$UploadResponse = Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines -WebSession $Session
话虽如此,curl 现在默认包含在 Windows 10+ 中,并且在我看来要容易得多,您只需确保使用
curl.exe
,因为 curl
是一个 invoke-webrequest 别名 -_-