使用Stream的RestSharp AddFile

时间:2015-09-30 22:29:58

标签: upload streaming restsharp

我正在使用RestSharp(Visual Studio 2013中的版本105.2.3.0,.net 4.5)来调用NodeJS托管的Web服务。我需要做的一个调用是上传文件。使用RESTSharp请求,如果我从我的端检索流到一个字节数组并将其传递给AddFile,它工作正常。但是,我更倾向于流内容而不是在服务器内存中加载整个文件(文件可以是100的MB)。

如果我设置一个动作来复制我的流(见下文),我在System.Net.ProtocolViolationException的“MyStream.CopyTo”行中得到一个异常(要写入流的字节超过Content-Length字节尺寸指定)。在调用client.Execute之后,在Action块中抛出此异常。

从我读到的内容来看,我不应该手动添加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...
    }

3 个答案:

答案 0 :(得分:12)

我有同样的问题。我最终在Files集合上使用了.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
});            

答案 1 :(得分:1)

以下代码适用于我使用rest sharp上传csv文件。 Web服务API已被调用。

var client = new RestClient(<YOUR API END URL >);
var request = new RestRequest(Method.POST) ;
request.AlwaysMultipartFormData = true;
request. AddHeader("Content-Type", "multipart/form-data");
request.AddHeader("X-API-TOKEN", <Your Unique Token - again not needed for certain calls>);
request.AddParameter(<Your parameters.....>);
request.AddFile("file", currentFileLocation, contentType);
request.AddParameter("multipart/form-data", fileName, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
var response = client.Execute(request);

答案 2 :(得分:0)

以下示例-如何使用预签名URL将图像文件上传到Amazon S3存储桶。 RestSharp库。

public void UploadToS3PresignedUrl(string s3presignedUrl, byte[] imageByte)
{
    var request = new RestRequest(s3presignedUrl, Method.PUT);

    request.AddHeader("Content-Type", "image/jpeg");
    request.AddParameter("application/octet-stream", imageByte, ParameterType.RequestBody);

    var client = new RestClient();
    client.Execute(request);
}