RestSharp AddFile 使用 Stream

Posted

技术标签:

【中文标题】RestSharp AddFile 使用 Stream【英文标题】:RestSharp AddFile Using Stream 【发布时间】:2015-12-28 20:38:18 【问题描述】:

我正在使用 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...
    

【问题讨论】:

我刚刚发现了同样的问题。我的线 request.AddFile("file", stream =&gt; data.CopyTo(stream), fileName) 被 RestSharp 版本 105.2.0+ 破坏了。降级到 105.1.0 时它工作正常。还没来得及调查 git-repo 中的变化... 我也有这个问题。降级到 105.1.0 有所帮助,但我还对旧的 issue on github 添加了评论 你可以使用 AddFileBytes 是某种包装器 【参考方案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】:

我有同样的问题。我最终在 Files 集合上使用了 .Add() 。它有一个与 AddFile() 具有相同参数的 FileParameter 参数,您只需添加 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
);            

【讨论】:

input 是什么?我对此有错误。如何申报? @Root 如果您的文件为byte[],您可以将其转换为MemoryStream 并引用它。对我来说就像一个魅力:Stream stream = new MemoryStream(fileBytes); 然后在下面删除有问题的行并引用您的新 Stream 对象。 这已经过时了。 req.Files.Add 在 v4.0 中不再存在

以上是关于RestSharp AddFile 使用 Stream的主要内容,如果未能解决你的问题,请参考以下文章

如何使用RestSharp发送请求

如何使用 RestSharp 使用 JWT 访问令牌和用户声明

使用 restsharp 反序列化 json 字符串

如何将 RestSharp 与 async/await 一起使用

RestSharp​.net REST/HTTP 工具库

如何在 RestSharp 中使用 OAuth2