RestSharp AddFile 使用 Stream

时间:2023-03-29
本文介绍了RestSharp AddFile 使用 Stream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I am using RestSharp (version 105.2.3.0 in Visual Studio 2013, .net 4.5) to call a NodeJS hosted webservice. One of the calls I need to make is to upload a file. Using a RESTSharp request, if I retrieve the stream from my end into a byte array and pass that to AddFile, it works fine. However, I would much rather stream the contents and not load up entire files in server memory (the files can be 100's of MB).

如果我设置了一个操作来复制我的流(见下文),我会在 System.Net.ProtocolViolationException 的MyStream.CopyTo"行出现异常(要写入流的字节超过 Content-Length 字节指定的大小).在调用 client.Execute 后,此异常会在 Action 块内引发.

If I set up an Action to copy my stream (see below), I get an exception at the "MyStream.CopyTo" line of System.Net.ProtocolViolationException (Bytes to be written to the stream exceed the Content-Length bytes size specified). This exception is thrown within the Action block after client.Execute is called.

根据我的阅读,我不应该手动添加 Content-Length 标头,如果我这样做也无济于事.我尝试将 CopyTo 缓冲区设置得太小和太大,以及完全忽略它,但无济于事.有人可以告诉我我错过了什么吗?

From what I read, I should not be manually adding a Content-Length header, and it doesn't help if I do. I have tried setting CopyTo buffer too small and large values, as well as omitting it entirely, to no avail. Can somebody give me a hint on what I've missed?

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

推荐答案

我也遇到了同样的问题.我最终在 Files 集合上使用了 .Add() .它有一个与 AddFile() 具有相同参数的 FileParameter 参数,您只需添加 ContentLength:

I had the same issue. I ended up using the .Add() on the Files collection. It has a FileParameter param which has the same params as AddFile(), you just have to add the 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
});            

这篇关于RestSharp AddFile 使用 Stream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何在没有回发的情况下使用 JavaScript 上传文件? 下一篇:YouTube C# API V3,如何恢复中断的上传?

相关文章