2015-09-30 2 views
13

Я использую RestSharp (версия 105.2.3.0 в Visual Studio 2013, .net 4.5) для вызова веб-службы, размещенной в NodeJS. Один из вызовов, который мне нужно сделать, - загрузить файл. Используя запрос RESTSharp, если я получаю поток с моего конца в массив байтов и передаю его в AddFile, он отлично работает. Тем не менее, я бы скорее потоком содержимого и не загружать целые файлы в память сервера (файлы могут быть 100-х MB).RestSharp AddFile Использование Stream

Если я установил действие для копирования моего потока (см. Ниже), я получаю исключение в строке «MyStream.CopyTo» System.Net.ProtocolViolationException (байты, которые должны быть записаны в поток, превышают длину содержимого размер байта). Это исключение выбрано внутри блока Action после client.Execute.

Из того, что я читал, я не должен вручную добавлять заголовок Content-Length, и это не помогает, если я это делаю. Я попытался настроить буфер CopyTo на малые и большие значения, так же как и исключить его полностью, безрезультатно. Может кто-нибудь дать мне намек на то, что я пропустил?

// 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

Я только что обнаружил ту же проблему. Моя строка 'request.AddFile (" file ", stream => data.CopyTo (stream), fileName)' нарушена с RestSharp версии 105.2.0+. При понижении до 105.1.0 он работает нормально. Не успел исследовать изменения в git-repo еще ... – anve

+0

У меня тоже есть эта проблема. Снижение до 105.1.0 помогло, но я также добавил комментарий к старому [issue on github] (https://github.com/restsharp/RestSharp/issues/70) – Dmitry

+0

Вы можете использовать AddFileBytes - это своего рода оболочка – hpfs

ответ

6

У меня была та же проблема. Я закончил использование .Add() в коллекции файлов. У него есть параметр FileParameter, который имеет те же параметры, что и AddFile(), вам просто нужно добавить 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 
});    
Смежные вопросы