Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can RestSharp send binary data without using a multipart content type?

Tags:

c#

restsharp

I have been using AddParameter to include XML bodies in my HTTP requests:

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

However, this does not seem to work for non-string bodies. (RestSharp's Http.RequestBody is a string for some reason.) I tried using AddFile(), but I can't find any way to avoid encoding the "file" as multipart/form, even if I've only supplied a single object.

I'm not at all opposed to underhanded reflection to solve this problem, but I'm hoping to avoid modifying the source just to send arbitrary data in an HTTP request.

Edit: regarding the requests I'm trying to send, they just look like this:

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

<arbitrary bytes>

Ideally, I'd like to use the same calls to send a different content type:

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

<other arbitrary bytes>
like image 614
ladenedge Avatar asked Apr 15 '12 02:04

ladenedge


People also ask

Does RestSharp use Httpclient?

RestSharp is an open-source HTTP Client library that we can use to consume APIs. Based on that, we can install it using NuGet Package Manager. Although RestSharp can call any API using the HTTP protocol, the purpose of RestSharp is to consume the REST APIs. RestSharp supports both synchronous and asynchronous requests.

What is RestSharp library?

RestSharp is a C# library used to build and send API requests, and interpret the responses. It is used as part of the C#Bot API testing framework to build the requests, send them to the server, and interpret the responses so assertions can be made.


3 Answers

There have been some modifications made in the latest version that allow a single file to be used without creating a multipart form request. Here is a gist that shows and example:

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

like image 164
Michael Avatar answered Sep 28 '22 03:09

Michael


I ran into the same issue. I had to upload exactly one file and use a specific content type for communicating with an REST Interface. You could modify Http.RequestBody to byte[] (and all dependencies on that), but i think its easier this way:

I modified RestSharp, so that it only use Multipart Encoding when number of Files > 1 or number of Files = 1 and there is also body or other post data set.

You have to modify Http.cs on Line 288 from

if(HasFiles)

to

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

For Http.Sync.cs modify PreparePostData from

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

    PreparePostBody(webRequest);
}

to

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);
}

If you use the async version, you have to modify the code similar to the above in Http.Async.cs.

Now u can use RestSharp like this

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

Client.Execute(request);

AddFile also provides an overload for setting direct byte[] data instead of a path. Hope that helps.

like image 24
Dresel Avatar answered Sep 28 '22 01:09

Dresel


In the latest version of RestSharp at the time of writing (version 104), the modification needs to be in Http.Sync.cs , method PreparePostData, which should read as:

    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);
    }
like image 43
Vincent Sos Avatar answered Sep 28 '22 02:09

Vincent Sos