@@ -0,0 +1,135 @@
using System ;
using System . IO ;
using System . Net ;
using System . Net . Http ;
using System . Threading . Tasks ;
namespace TestConsole
{
// From https://stackoverflow.com/a/41392145/4213397
internal class ProgressableStreamContent : HttpContent
{
/// <summary>
/// Lets keep buffer of 20kb
/// </summary>
private const int defaultBufferSize = 5 * 4096 ;
private HttpContent content ;
private int bufferSize ;
//private bool contentConsumed;
private Action < long , long > progress ;
public ProgressableStreamContent ( HttpContent content , Action < long , long > progress ) : this ( content ,
defaultBufferSize , progress )
{
}
public ProgressableStreamContent ( HttpContent content , int bufferSize , Action < long , long > progress )
{
if ( content == null )
{
throw new ArgumentNullException ( "content" ) ;
}
if ( bufferSize <= 0 )
{
throw new ArgumentOutOfRangeException ( "bufferSize" ) ;
}
this . content = content ;
this . bufferSize = bufferSize ;
this . progress = progress ;
foreach ( var h in content . Headers )
{
this . Headers . Add ( h . Key , h . Value ) ;
}
}
protected override Task SerializeToStreamAsync ( Stream stream , TransportContext context )
{
return Task . Run ( async ( ) =>
{
var buffer = new Byte [ this . bufferSize ] ;
long size ;
TryComputeLength ( out size ) ;
var uploaded = 0 ;
using ( var sinput = await content . ReadAsStreamAsync ( ) )
{
while ( true )
{
var length = sinput . Read ( buffer , 0 , buffer . Length ) ;
if ( length <= 0 ) break ;
//downloader.Uploaded = uploaded += length;
uploaded += length ;
progress ? . Invoke ( uploaded , size ) ;
//System.Diagnostics.Debug.WriteLine($"Bytes sent {uploaded} of {size}");
stream . Write ( buffer , 0 , length ) ;
stream . Flush ( ) ;
}
}
stream . Flush ( ) ;
} ) ;
}
protected override bool TryComputeLength ( out long length )
{
length = content . Headers . ContentLength . GetValueOrDefault ( ) ;
return true ;
}
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
content . Dispose ( ) ;
}
base . Dispose ( disposing ) ;
}
}
class Program
{
static void Main ( string [ ] args )
{
upload ( ) ;
Console . ReadKey ( ) ;
}
static async void upload ( )
{
using ( var client = new HttpClient ( ) )
using ( var multiForm = new MultipartFormDataContent ( ) )
{
client . Timeout = TimeSpan . FromMinutes ( 5 ) ; // You may need this if you are uploading a big file
var file = new ProgressableStreamContent ( new StreamContent ( File . OpenRead ( "C://t.txt" ) )
, ( sent , total ) => {
Console . SetCursorPosition ( 1 , 0 ) ; // Remove last line
Console . WriteLine ( "\b Uploading " + ( ( float ) sent / total ) * 100f ) ;
} ) ;
multiForm . Add ( file , "document" , "1.txt" ) ; // Add the file
multiForm . Add ( new StringContent ( "value" ) , "key" ) ; // Add some other fields if you like
var response = await client . PostAsync ( "https://example.com/upload" , multiForm ) ;
Console . WriteLine ( response . StatusCode ) ;
if ( response . StatusCode == HttpStatusCode . OK )
{
string res = await response . Content . ReadAsStringAsync ( ) ;
Console . WriteLine ( res ) ;
}
}
}
}
}