10

AddParameterHTTPリクエストにXML本文を含めるために使用しています。

request.AddParameter(contentType, body, ParameterType.RequestBody);

ただし、これは文字列以外のボディでは機能しないようです。(RestSharpHttp.RequestBodyは何らかの理由で文字列です。)を使用してみましたが、オブジェクトを1つだけ指定した場合でも、「ファイル」をmultipart/formAddFile()としてエンコードすることを回避する方法が見つかりません。

私はこの問題を解決するために手に負えないリフレクションにまったく反対していませんが、HTTPリクエストで任意のデータを送信するためだけにソースを変更することは避けたいと思っています。

編集:私が送信しようとしているリクエストに関しては、次のようになります。

PUT ... HTTP/1.1
Accept: application/vnd...
Authorization: Basic ...
Content-Type: application/octet-stream

<arbitrary bytes>

理想的には、同じ呼び出しを使用して別のコンテンツタイプを送信したいと思います。

PUT ... HTTP/1.1
Accept: application/vnd...
Authorization: Basic ...
Content-Type: application/vnd...

<other arbitrary bytes>
4

6 に答える 6

8

最新バージョンでは、マルチパートフォームリクエストを作成せずに単一のファイルを使用できるようにいくつかの変更が加えられています。例を示す要点は次のとおりです。

https://gist.github.com/hallem/5faaa6bebde50641e928

于 2015-01-16T23:10:06.860 に答える
5

私は同じ問題に遭遇しました。正確に1つのファイルをアップロードし、RESTインターフェイスとの通信に特定のコンテンツタイプを使用する必要がありました。Http.RequestBodyをbyte[](およびそれに依存するすべての依存関係)に変更できますが、この方法の方が簡単だと思います。

RestSharpを変更して、ファイル数>1またはファイル数=1の場合にのみマルチパートエンコーディングを使用し、本文またはその他の投稿データセットもあるようにしました。

288行目のHttp.csをから変更する必要があります

if(HasFiles)

if(Files.Count > 1 || (Files.Count == 1 && (HasBody || Parameters.Any())))

Http.Sync.csの場合、PreparePostDataをから変更します。

private void PreparePostData(HttpWebRequest webRequest)
{
    if (HasFiles)
    {
        webRequest.ContentType = GetMultipartFormContentType();
        using (var requestStream = webRequest.GetRequestStream())
        {
            WriteMultipartFormData(requestStream);
        }
    }

    PreparePostBody(webRequest);
}

private void PreparePostData(HttpWebRequest webRequest)
{
    // Multiple Files or 1 file and body and / or parameters
    if (Files.Count > 1 || (Files.Count == 1 && (HasBody || Parameters.Any())))
    {
        webRequest.ContentType = GetMultipartFormContentType();
        using (var requestStream = webRequest.GetRequestStream())
        {
            WriteMultipartFormData(requestStream);
        }
    }
    else if (Files.Count == 1)
    {
        using (var requestStream = webRequest.GetRequestStream())
        {
            Files.Single().Writer(requestStream);
        }
    }

    PreparePostBody(webRequest);
}

非同期バージョンを使用する場合は、上記のHttp.Async.csのコードと同様のコードを変更する必要があります。

これで、RestSharpを次のように使用できます

IRestRequest request = new RestRequest("urlpath", Method.PUT);
request.AddHeader("Content-Type", "application/zip");
request.AddFile("Testfile", "C:\\File.zip");

Client.Execute(request);

AddFileは、パスの代わりに直接byte[]データを設定するためのオーバーロードも提供します。お役に立てば幸いです。

于 2012-08-09T14:56:31.817 に答える
5

執筆時点でのRestSharpの最新バージョン(バージョン104)では、変更はHttp.Sync.cs、メソッドPreparePostDataにある必要があり、次のように読み取る必要があります。

    private void PreparePostData(HttpWebRequest webRequest)
    {

        // Multiple Files or 1 file and body and / or parameters
        if (Files.Count > 1 || (Files.Count == 1 && (HasBody || Parameters.Count>0)))
        {
            webRequest.ContentType = GetMultipartFormContentType();
            using (var requestStream = webRequest.GetRequestStream())
            {
                WriteMultipartFormData(requestStream);
            }
        }
        else if (Files.Count == 1)
        {
            using (var requestStream = webRequest.GetRequestStream())
            {
                Files[0].Writer(requestStream);
            }
        }
        PreparePostBody(webRequest);
    }
于 2012-09-19T18:50:13.510 に答える
4

私は同じ問題を抱えていましたが、コードをフォークするのが好きではなく、ドキュメントに「RequestBody:AddBody()で使用されます(直接使用することはお勧めしません)」と記載されているMichaelによって提案された代替案が好きではありませんでした。

代わりに、RestClient.HttpFactoryを自分のものに置き換えました。

RestClient client = GetClient();

var bytes = await GetBytes();
client.HttpFactory = new FactoryWithContent { GetBytes = () => new Bytes(bytes, "application/zip") };

var request = new RestRequest();
return await client.ExecutePostTaskAsync(request);

BytesとFactoryWithContentは次のようになります。

public class Bytes
{
    public Bytes(byte[] value, string type)
    {
        Value = value;
        Type = type;
    }

    public byte[] Value { get; private set; }
    public string Type { get; private set; }
}

public class FactoryWithContent : IHttpFactory
{
    public IHttp Create()
    {
        var http = new Http();

        var getBytes = GetBytes;
        if (getBytes != null)
        {
            var bs = getBytes();
            http.RequestBodyBytes = bs.Value;
            http.RequestContentType = bs.Type;
        }

        return http;
    }

    public Func<Bytes> GetBytes { get; set; }
}
于 2015-01-09T14:44:55.550 に答える
3

私も同じ問題を抱えていました。RestSharpの動作が少し変わっていることがわかりました。

動作していません:

request.Parameters.Add(new Parameter() {
  ContentType = "application/x-www-form-urlencoded",
  Type = ParameterType.RequestBody,
  Value = bytes
});

WORKING(名前としてコンテンツタイプを追加):

request.Parameters.Add(new Parameter() {
  Name = "application/x-www-form-urlencoded", // This is the 'funny' part
  ContentType = "application/x-www-form-urlencoded",
  Type = ParameterType.RequestBody,
  Value = bytes
});

私はここのコメントに基づいてこの解決策を試しました:https ://github.com/restsharp/RestSharp/issues/901

「...name値はContent-Typeヘッダーとして使用され、contentType値は無視されます」と記載されています。

Content-Typeパラメーターとして値を追加する必要もありませんが、将来のバグ修正によって動作が変更され、名前の代わりにContent-Typeを使用する必要が生じる可能性があります。

于 2018-04-24T10:03:19.960 に答える
0

RequestStreamCallbackメソッドには、Http.Async.csへの変更も必要です。私は実際にこの修正をリポジトリに取り込む作業を行っており、現在プロジェクトの保守を支援しているため、Nugetに公開しています。このために作成された問題へのリンクは次のとおりです:https ://github.com/restsharp/RestSharp/issues/583

于 2014-10-17T18:55:20.670 に答える