1

I am creating a PCL within Xamarin that is using the Microsoft.Net.Http Nuget package for a HttpClient class. I use the HttpClient to post an audio file to a web API. This has worked well for me up to this point, but now I am having troubles while trying to get the file to be streamed to the API. The API says in its documentation to add set a "Transfer-encoding" header to be "chunked" in order for streaming of the file to be accepted. I can't add this header manually the way I have with other headers, instead a set it from a property of HttpClient. The problem is that when I call HttpClient.PostAsync(), it throws an exception because the SendChunk property of a HttpWebRequest is not True. I'm assuming that the HttpWebRequest object is creating by HttpClient, but I don't know how I can set the SendChunk property to True. When I create a HttpWebRequest object by itself, the SendChunk property is not accessible even though it is a public property. I am guessing that it has something to do with being a PCL, but the SeundChunk property does show up in the Microsoft.Net.Http Assembly.

In short, I need to get the header "Transfer-encoding : chunked" into my HttpClient headers, but can't. How can I add this header while certain properties are unavailable because I am working in a PCL?

public async Task<string> PostAsync(string url, Stream content, Dictionary<string,string> requestHeaders, Dictionary<string,string> contentHeaders)
    {
        var httpClient = new System.Net.Http.HttpClient();
        var httpContent = new System.Net.Http.StreamContent(content);

        httpClient.Timeout = TimeSpan.FromSeconds(20);
        httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;

        if (requestHeaders != null)
        {
            foreach (var headerName in requestHeaders.Keys)
            {
                httpClient.DefaultRequestHeaders.Add(headerName, requestHeaders[headerName]);
            }
        }
        if (contentHeaders != null)
        {
            foreach (var headerName in contentHeaders.Keys)
            {
                httpContent.Headers.Add(headerName, contentHeaders[headerName]);
            }
        }

        HttpResponseMessage response = null;

        try
        {
            response = await httpClient.PostAsync(url, httpContent);
        }

EDIT:

I've update my code to look like this

             HttpClientHandler handler = new HttpClientHandler();

        System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient(handler);
        httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url);

        var httpContent = new System.Net.Http.StreamContent(content);

        request.Content = httpContent;

        if (handler.SupportsTransferEncodingChunked())
        {
            request.Headers.TransferEncodingChunked = true;
        }

        HttpResponseMessage response = null;


            response = await httpClient.SendAsync(request);

SendAsync throws an exception saying "System.Net.ProtocolViolationException: SendChunked should be true". I modeled my code after this post http://blogs.msdn.com/b/bclteam/archive/2013/02/18/portable-httpclient-for-net-framework-and-windows-phone.aspx.

3
  • Hi, did you get anywhere with this problem? I'm getting the same here! Thanks. Commented Aug 26, 2015 at 16:49
  • Unfortunately, I have not. I've basically given up on streaming the file for now after spending a couple days trying to get this working. I'll let you know if I'm ever able to get it figured out though. Commented Aug 27, 2015 at 17:34
  • Here's my little piece of advice, check my Request http client, maybe it can help . Commented Jul 8, 2016 at 1:58

2 Answers 2

1

I'm trying to deal with a similar situation. I've come across a couple of options that may help.

ModernHTTPClient

or this Rest Sharp

As a status update, I did get ModernHTTPClient to work. My solution though I had to delete the contents of my package folder, then install that nuget package, and then restore my other packages. Otherwise the solution was a simple as

var httpClient = new HttpClient(new NativeMessageHandler());
Sign up to request clarification or add additional context in comments.

Comments

0

I found a handly library from this link on the Xamarin Forums; https://forums.xamarin.com/discussion/25274/httpclient-in-pcl

There is a Nuget Package by Robert McLaws and Richard Beauchamp called PortableRest.

Its a library for consuming REST APIs from Portable Class Libraries (.NET 4.5, Silverlight 5, Windows Phone 8.x, and Windows 8.x). Designed to be partially drop-in compatible with RestSharp.

GitHub link here: https://github.com/AdvancedREI/PortableRest Nuget package here: https://www.nuget.org/packages/PortableRest

Source: https://forums.xamarin.com/discussion/25274/httpclient-in-pcl

To use this:

var client = new RestClient { BaseUrl = Constants.API_BASE_URI };
var request = new RestRequest("Token", HttpMethod.Post, ContentTypes.FormUrlEncoded);
request.AddHeader("Accept", "application/json");
request.AddParameter("grant_type", "password", ParameterEncoding.UriEncoded);
request.AddParameter("username", userEntry.Text, ParameterEncoding.UriEncoded);
request.AddParameter("password", passwordEntry.Text, ParameterEncoding.UriEncoded);

var result = await client.SendAsync<AuthToken>(request);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.