upload - parametertype - restsharp request resource
RestSharp AddFile utilizando Stream (1)
Estoy utilizando RestSharp (versión 105.2.3.0 en Visual Studio 2013, .net 4.5) para llamar a un servicio web alojado en NodeJS. Una de las llamadas que necesito hacer es cargar un archivo. Usando una solicitud RESTSharp, si recupero la secuencia de mi extremo en una matriz de bytes y la paso a AddFile, funciona bien. Sin embargo, preferiría transmitir los contenidos y no cargar archivos completos en la memoria del servidor (los archivos pueden ser de 100 MB).
Si configuro una Acción para copiar mi flujo (ver más abajo), obtengo una excepción en la línea "MyStream.CopyTo" de System.Net.ProtocolViolationException (los bytes que se escriben en el flujo exceden el tamaño de bytes de longitud de contenido especificado) . Esta excepción se produce dentro del bloque de acción después de que se llame a client.Execute.
Por lo que leí, no debería agregar manualmente un encabezado Content-Length, y no ayuda si lo hago. He intentado configurar el búfer CopyTo en valores pequeños y grandes, así como omitirlo por completo, sin éxito. ¿Alguien puede darme una pista sobre lo que me he perdido?
// 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...
}
Tuve el mismo problema. Terminé usando el .Add () en la colección de Archivos. Tiene un parámetro FileParameter que tiene los mismos parámetros que AddFile (), solo tiene que agregar 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
});