C#.NetCore HttpClient PostAsync多部分表单数据,带有文件附件和进度,供PowerShell使用

C#.NetCore HttpClient PostAsync多部分表单数据,带有文件附件和进度,供PowerShell使用,c#,powershell,httpclient,dotnet-httpclient,C#,Powershell,Httpclient,Dotnet Httpclient,我正在更新一些PowerShell代码,这些代码使用sdSystem.Net.HttpWebRequest处理与web服务之间的文件传输。System.IO.FileStream类在处理使用HttpWebRequest传输到web服务的文件流时存在一个主要问题,Microsoft不会在DotNetCore中修复或解决该问题,因此PowerShellCore()也不会解决该问题。实际上,在.NetCore针对FileStream和PowerShellCore/PowerShell7的遗留API实现

我正在更新一些PowerShell代码,这些代码使用sd
System.Net.HttpWebRequest
处理与web服务之间的文件传输。
System.IO.FileStream
类在处理使用
HttpWebRequest
传输到web服务的文件流时存在一个主要问题,Microsoft不会在DotNetCore中修复或解决该问题,因此PowerShellCore()也不会解决该问题。实际上,在.NetCore针对
FileStream
和PowerShellCore/PowerShell7的遗留API实现中,一个运行到
流太长的异常。因此,我有以下经过验证且工作正常的PowerShell代码,我正在尝试使用
HttpClient
将其转换为C#async类方法,以将文件异步上载到基于Apache/Spring的REST API服务:

$Hostname=“somewebserver”
$Method=“POST”
$File=Get ChildItem C:\Directory\File.iso
$FSOpenMode=[System.IO.FileMode]::打开
$FSRead=[System.IO.FileAccess]::Read
#使用FileStream读取文件
$fs=[IO.FileStream]::新建($File.FullName、$FSOpenMode、$FSRead)
[void]$fs.FlushAsync()
尝试
{
#设置将作为上载目标的URL
$url=“https://{0}/upload?uploadfilename={1}”-f$Hostname,$File.Name
$\u DispositionContentType=“应用程序/八位字节流”
[System.Net.httpWebRequest]$uploadRequest=[System.Net.WebRequest]::创建($uri)
$uploadRequest.Method=$Method
$boundary=“------------------------------------”+[DateTime]::Now.Ticks.ToString(“x”)
[byte[]$BoundaryBytes=[System.Text.Encoding]::UTF8.GetBytes(“`r`n--”+$boundary+“`r`n”);
$disposition=“Content disposition:form data;name=`“file`”;filename=`{0}`;`r`n内容类型:{1}`r`n`r`n”-f$file.name,$\u DispositionContentType
[byte[]$ContentDispBytes=[System.Text.Encoding]::UTF8.GetBytes($disposition);
[byte[]$EndBoundaryBytes=[System.Text.Encoding]::UTF8.GetBytes(“`r`n--”+$boundary+”--`r`n”)
$uploadRequest.Timeout=1200000
$uploadRequest.ContentType=“多部分/表单数据;边界={0}”-f$boundary
$uploadRequest.Headers.Item(“auth”)=“SessionID”
$uploadRequest.Headers.Item(“uploadfilename”)=$File.Name
$uploadRequest.AllowWriteStreamBuffering=$true
$uploadRequest.SendChunked=$true
$uploadRequest.ContentLength=$BoundaryBytes.length+$ContentDispBytes.length+$File.length+$EndBoundaryBytes.length
$uploadRequest.Headers.Item(“ContentLength”)=$BoundaryBytes.length+$ContentDispBytes.length+$File.length+$EndBoundaryBytes.length
$rs=$uploadRequest.GetRequestStream()
[void]$rs.FlushAsync()
[字节[]]$readbuffer=[字节[]]::新建(4096*1024)
$rs.write($BoundaryBytes,0,$BoundaryBytes.Length);
$rs.write($ContentDispBytes,0,$ContentDispBytes.Length);
#这用于跟踪文件上载进度。
$numBytesToRead=$fs.Length
[int64]$numBytesRead=0
$\u sw=[System.Diagnostics.Stopwatch]::StartNew()
$\u progresssw=[System.Diagnostics.Stopwatch]::StartNew()
而($bytesRead=$fs.Read($readbuffer,0,$readbuffer.length))
{
[void]$fs.Flush()
$rs.write($readbuffer,0,$bytesRead)
[void]$fs.Flush()
[作废]$rs.Flush()
#在读取操作期间,跟踪我们的位置
$\u numbytes读取+=$bytesRead
#每写入200ms和1MB刷新一次缓冲区
如果($\u progressw.appeased.total毫秒-ge 200-和$\u numbytes读取%100mb-等式0)
{
[作废]$rs.flush()
}
#使用Write Progress cmd let显示上载文件的进度。
[Int]$\u percent=[math]::地板($\u numBytesRead/$fs.Length)*100)
#计算吞吐量所用的时间
[Int]$\u运行时间=$\u sw.ElapsedMilliseconds/1000
如果($\u已过去-ne 0)
{
[single]$\u transferrate=[Math]::舍入($\u numBytesRead/$\u已用)/1mb)
}
其他的
{
[单一]$\u转移率=0.0
}
$status=“({0:0}MB的{1:0}MB已传输@{2}MB/s)已完成{3}%”-f($\u numBytesRead/1MB),($numBytesToRead/1MB),$\u传输率,$\u%
#通过仅在指定的时间间隔刷新进度来处理写入进度差如何增加文件传输过程的延迟
如果($\u progressw.eassed.total毫秒-ge 500)
{
如果($\u numbytes读取%1mb-等式0)
{
写入进度-活动“上载文件”-状态(“上载“{0}”-f$File.Name”-当前操作$status-完成百分比$\u%
}
}
}
$fs.close()
#将endboundary写入文件的二进制上载流
$rs.write($EndBoundaryBytes,0,$EndBoundaryBytes.Length)
$rs.close()
$\开关停止()
$\软件重置()
写入进度-活动“上载文件”-状态(“上载“{0}”-f$File.Name)-完成
}
catch[系统异常]
{
如果有的话($fs)
{
$fs.close()
}
如果($\u软件正在运行)
{
$\开关停止()
$\软件重置()
}
#如果仍然存在,则进行处置
如果有的话(卢比)
{
$rs.close()
}
扔$_
}
尝试
{
#指示我们正在等待API在写入进度显示中处理上载的文件
写入进度-活动“上载文件”-状态(“上载{0}”-f$File.Name)-CurrentOperation“等待来自设备的完成响应”-percentComplete$\u%
#获取API对识别文件进度的响应
[Net.httpWebResponse]$WebResponse=$uploadRequest.getResponse()
$uploadResponseStream=$WebResponse.GetResponseStream()
#读取响应并转换为JSON
$reader=[System.IO.StreamReader]::新建($uploadResponseStream)
$responseJson=$reader.ReadToEnd()
$uploadResponse=convertfromJSON$responseJson
$uploadResponseStream.Close()
$upl