2015-09-30 28 views
13

Sto usando RestSharp (versione 105.2.3.0 in Visual Studio 2013, .net 4.5) per chiamare un servizio web ospitato da NodeJS. Una delle chiamate che devo fare è caricare un file. Utilizzando una richiesta RESTSharp, se recupero il flusso dalla mia estremità in un array di byte e lo passo a AddFile, funziona perfettamente. Tuttavia, preferirei molto lo streaming dei contenuti e non caricare interi file nella memoria del server (i file possono essere di 100 di MB).RestSharp AddFile tramite Stream

Se si imposta un'azione per copiare il mio stream (vedere di seguito), ottengo un'eccezione nella riga "MyStream.CopyTo" di System.Net.ProtocolViolationException (i byte da scrivere nello stream superano il Content-Length dimensione byte specificata). Questa eccezione viene generata all'interno del blocco Action dopo che viene chiamato client.Execute.

Da quello che ho letto, non dovrei aggiungere manualmente un'intestazione Content-Length, e non aiuta se lo faccio. Ho provato a impostare il buffer CopyTo su valori piccoli e grandi, come se lo omettesse del tutto, inutilmente. Qualcuno può darmi un suggerimento su cosa ho perso?

// Snippet... 
    protected T PostFile<T>(string Resource, string FieldName, string FileName, 
     string ContentType, Stream MyStream, 
     IEnumerable<Parameter> Parameters = null) where T : new() 
    { 
     RestRequest request = new RestRequest(Resource); 
     request.Method = Method.POST; 

     if (Parameters != null) 
     { 
      // Note: parameters are all UrlSegment values 
      request.Parameters.AddRange(Parameters); 
     } 

     // _url, _username and _password are defined configuration variables 
     RestClient client = new RestClient(_url); 
     if (!string.IsNullOrEmpty(_username)) 
     { 
      client.Authenticator = new HttpBasicAuthenticator(_username, _password); 
     } 

     /* 
     // Does not work, throws System.Net.ProtocolViolationException, 
     // Bytes to be written to the stream exceed the 
     // Content-Length bytes size specified. 
     request.AddFile(FieldName, (s) => 
     { 
      MyStream.CopyTo(s); 
      MyStream.Flush(); 
     }, FileName, ContentType); 
     */ 

     // This works, but has to load the whole file in memory 
     byte[] data = new byte[MyStream.Length]; 
     MyStream.Read(data, 0, (int) MyStream.Length); 
     request.AddFile(FieldName, data, FileName, ContentType); 

     var response = client.Execute<T>(request); 

     // check response and continue... 
    } 
+1

Ho appena scoperto lo stesso problema. La mia riga 'request.AddFile (" file ", stream => data.CopyTo (stream), fileName)' è stata interrotta con RestSharp versione 105.2.0+. Quando esegui il downgrade a 105.1.0 funziona perfettamente. Non ho ancora avuto il tempo di indagare sui cambiamenti nel git-repo ... – anve

+0

Anche io ho questo problema. Il downgrade a 105.1.0 ha aiutato, ma ho anche aggiunto un commento al vecchio [problema su github] (https://github.com/restsharp/RestSharp/issues/70) – Dmitry

+0

Puoi usare AddFileBytes è una specie di wrapper – hpfs

risposta

6

Ho avuto lo stesso problema. Ho finito con l'uso di .Add() nella collezione Files. Ha un parametro FileParameter che ha gli stessi parametri di AddFile(), devi solo aggiungere ContentLength:

var req = GetRestRequest("Upload", Method.POST, null); 
//req.AddFile("file", 
// (s) => { 
//  var stream = input(imageObject); 
//  stream.CopyTo(s); 
//  stream.Dispose(); 
// }, 
// fileName, contentType); 

req.Files.Add(new FileParameter { 
    Name = "file", 
    Writer = (s) => { 
     var stream = input(imageObject); 
     stream.CopyTo(s); 
     stream.Dispose(); 
    }, 
    FileName = fileName, 
    ContentType = contentType, 
    ContentLength = contentLength 
});