23

I am trying to port the c# cloudinary api to mono and I am having some problems building up the http request.

I have separated out this method for setting up the request but the HttpWebRequest.ContentLength turns out to be -1 in mono, but is .net the content is properly built.

I am running the newest Xamarin Studio on a Mac and I am building a MONO / .NET 4.0 library Mono version: 2.10.12

EDIT: Simplified code, this test passes in Visual Studio but fails in Xamarin studio

EDIT: Code is pushed to github if anybody would like to help

    [Test]
    public void StreamTest()
    {
        var request = System.Net.HttpWebRequest.Create("http://foo.com");
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        using (var writer = new System.IO.StreamWriter(request.GetRequestStream()))
        {
            writer.Write("anything");
        }

        Assert.IsTrue(request.ContentLength > 0);
    }
Chris
  • 5,584
  • 9
  • 40
  • 58
terjetyl
  • 9,497
  • 4
  • 54
  • 72
  • What version of Mono are you running? – PhonicUK May 10 '13 at 13:05
  • I am building a MONO/.net 4.0 library. Newest Xamarin Studio – terjetyl May 10 '13 at 13:09
  • Can you check the *exact* version of Mono you're using. You can find out by running "mono -version" on the command line. – PhonicUK May 10 '13 at 13:23
  • Mono JIT compiler version 2.10.12 (mono-2-10/c9b270d Thu Mar 7 21:38:12 EST 2013) – terjetyl May 10 '13 at 15:30
  • 1
    `ContentLength` is not a property of *Stream* but *HttpWebRequest*. The implementation differences might be in *HttpWebRequest*. – I4V May 19 '13 at 21:45
  • Why do you need to check Request.ContentLenght? Because probably ContentLenght is calculated only when the request is started, so I think when GetResponse is called. The HTTP header can be set and so maybe ContentLenght is only calculated in this phase? If you need to known the ContentLength maybe you can first calculate it manually (for example using Encoding.GetBytes). – Davide Icardi May 22 '13 at 00:05
  • I've had a similar issue with the HttpListener in Mono, there was a bug with DateTime.Now always returning 0 on ARM platforms. This was fixed in later versions of Mono. Version 2.10 is somewhat old and there have been many changes since then, you might have much better luck with a more recent version. – TimothyP May 23 '13 at 08:56
  • @terjetyl , Hi, Were you able to fix it? I am currently working on porting for Mono-droid. Facing issues were same code run on desktop works but fails in xamarin. The tests in VS passes. – Ankur May 26 '15 at 09:14

2 Answers2

2

When you do

System.Net.HttpWebRequest.Create("http://foo.com");

you actually create an instance of the internal class System.Net.Browser.BrowserHttpWebRequest

Here is the inheritance hierarchy

System.Net.WebRequest
  System.Net.HttpWebRequest
    System.Net.Browser.PolicyBasedWebRequest
      System.Net.Browser.BrowserHttpWebRequest

The content length is handled in PolicyBasedWebRequest, initialized in ctor with -1 and never changed; I suggest you manually set it.

alexb
  • 971
  • 6
  • 12
0

See here: Xamarin Forum

It suggests that replacing this:

byte[] buffer = Encoding.GetEncoding("UTF-8").GetBytes(bundleString);
string result = Convert.ToBase64String(buffer);
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(result, 0, result.Length);
requestWriter.Flush();
requestWriter.Close();

with this:

httpWebRequest.ContentLength = bundleString.Length;
StreamWriter requestWriter = new StreamWriter(httpWebRequest.GetRequestStream());
requestWriter.Write(bundleString);
requestWriter.Flush();
requestWriter.Close();

fixed the problem. You can try this.

Ankur
  • 177
  • 1
  • 1
  • 8