web-dev-qa-db-ja.com

ストリームを使用したRestSharp AddFile

RestSharp(Visual Studio 2013のバージョン105.2.3.0、.net 4.5)を使用して、NodeJSがホストするWebサービスを呼び出しています。私がしなければならない呼び出しの1つは、ファイルをアップロードすることです。 RESTSharpリクエストを使用して、ストリームを最後からバイト配列に取得し、それをAddFileに渡すと、正常に動作します。ただし、コンテンツをストリーミングし、サーバーのメモリにファイル全体をロードしない方がいいです(ファイルは数百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...
    }
17
Jason

同じ問題がありました。結局、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
});            
12
Ben

次のコードは、レストシャープを使用して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);
1
Paul George