Bug 20589 - "Microsoft HTTP Client Libraries" NuGet causes "System.InvalidOperationException" from System.Lightup.Call()
Summary: "Microsoft HTTP Client Libraries" NuGet causes "System.InvalidOperationExcept...
Alias: None
Product: Visual Studio Extensions
Classification: Xamarin
Component: iOS ()
Version: 3.1
Hardware: PC Mac OS
: High critical
Target Milestone: 3.8
Assignee: mag@xamarin.com
: 17936 ()
Depends on:
Reported: 2014-06-13 17:35 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2015-06-18 20:09 UTC (History)
11 users (show)

Is this bug a regression?: ---
Last known good build:

Test case (27.31 KB, application/zip)
2014-06-13 17:35 UTC, Brendan Zagaeski (Xamarin Team, assistant)
App.config for workaround (430 bytes, application/octet-stream)
2014-06-13 17:36 UTC, Brendan Zagaeski (Xamarin Team, assistant)

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Brendan Zagaeski (Xamarin Team, assistant) 2014-06-13 17:35:22 UTC
Created attachment 7070 [details]
Test case

This is a new report for the old bug 17936 to provide an up-to-date starting point, a test case, and information about workarounds.

## Steps to reproduce

1. Build the attached test case in Visual Studio, and run it on an iOS device.

2. Tap the "Click me" button.

## Result

> Unhandled managed exception: Operation is not valid due to the current state of the object (System.InvalidOperationException)
>   at System.Lightup.Call[HttpWebRequest,Int64] (System.Delegate& storage, System.Net.HttpWebRequest instance, System.String methodName, Int64 parameter) [0x00000] in <filename unknown>:0 
>   at System.Lightup.Set[HttpWebRequest,Int64] (System.Delegate& storage, System.Net.HttpWebRequest instance, System.String propertyName, Int64 value) [0x00000] in <filename unknown>:0 
>   at System.Net.HttpWebRequestLightup.SetContentLength (System.Net.HttpWebRequest instance, Int64 value) [0x00000] in <filename unknown>:0 
>   at System.Net.Http.HttpWebRequest.set_ContentLength (Int64 value) [0x00000] in <filename unknown>:0 
>   at System.Net.Http.HttpClientHandler.StartRequest (System.Object obj) [0x00000] in <filename unknown>:0 
> --- End of stack trace from previous location where exception was thrown ---
>   at System.Runtime.ExceptionServices.ExceptionDis
> patchInfo.Throw () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62 
>   at System.Runtime.CompilerServices.TaskAwaiter`1[System.String].GetResult () [0x00000] in <filename unknown>:0 
>   at HttpAsyncTest.MyViewController+<<ViewDidLoad>b__0>d__2.MoveNext () [0x0001b] in c:\Users\%USERNAME%\Desktop\HttpNugetTest\HttpAsyncTest\MyViewController.cs:39 

## Expected result

No exception, and the HTML content from www.example.com gets printed via `Console.WriteLine()`.

## Workaround

Follow the steps under "Close to the finish line" on [1]. Optionally, change the "newVersion" to "". Or simply add the attached `app.config` to the HttpAsyncTest project. This `app.config` redirects all versions of `System.Net.Http` so that the final app will contain the Xamarin.iOS assembly rather than the NuGet version. 

> [1] http://motzcod.es/post/78863496592/portable-class-libraries-httpclient-so-happy

If you set "newVersion" to "", the exception will return.

## Alternative workaround

In the "HttpAsyncLibrary" project, set the "CopyLocal" property for the "System.Net.Http" assembly to "False".

## Additional information

The assembly version number of System.Net.Http was recently changed to

> https://github.com/mono/mono/commit/4c45fe93a1d288dc66df3d26059a167f6ae82785

Unfortunately, at least for this particular test case, it appears that the NuGet package causes the app project to request the "" NuGet version of the assembly. As a result, the final app bundle still contains the NuGet version instead of the Xamarin.iOS version:

> monodis --assembly ~/Library/Caches/Xamarin/mtbs/builds/HttpAsyncTest/2e353ad7-5ee3-4944-89f6-e5ba1c15178f/output/Debug/iPhone/HttpAsyncTest.app/System.Net.Http.dll | grep version
> Version:

## Version information

Note 1: the app runs without error when built and launched from Xamarin Studio on Mac.

Note 2: to workaround the XamarinVS 3.1 SDK sync bug #20588, I manually copied the assemblies from Xamarin.iOS to the Windows side.

### Mac
OS X 10.9.3

### Windows
Microsoft Visual Studio Professional 2013
Version 12.0.30501.00 Update 2
Microsoft .NET Framework
Version 4.5.51641

Xamarin (fb9b274179eab7ecc4c6ff10f9f7b789efe5b7f6)

Windows 8.1 64-bit (in VMWare)
Comment 1 Brendan Zagaeski (Xamarin Team, assistant) 2014-06-13 17:36:13 UTC
Created attachment 7071 [details]
App.config for workaround
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2014-06-13 17:43:23 UTC
*** Bug 17936 has been marked as a duplicate of this bug. ***
Comment 4 Ram Chandra 2014-06-16 06:45:43 UTC
I tried this issue and with the help of bug description I am able to reproduce this issue.

Steps to reproduce:

1. Open the attached project in VS 2013
2. Build and deploy the project on device.
3. Click on  "Click Me" button.
4. An "Unhandled managed exception" will be thrown.

When I press "Click Me" button on device I observed that I am also getting an "Unhandled managed exception".

I have also tried the workaround as mentioned on bug description. I have added the attached app.config file on "HttpAsyncTest" project. Which contains the new version "". I am not getting any exception and on the debug window it show "HTML" content, but when I changed the new version to "" I am getting the same exception.

Debug logs:  https://gist.github.com/anonymous/8bb172e96449c3397080

Environment Info:

Windows 7

Microsoft Visual Studio Professional 2013
Version 12.0.21005.1 REL
Microsoft .NET Framework
Version 4.5.50938

Xamarin (d3cf238e3845e930e312b6ec9b4c6c5437c33067)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android

Xamarin.iOS (d3cf238e3845e930e312b6ec9b4c6c5437c33067)
Visual Studio extension to enable development for Xamarin.iOS

Xamarin.iOS Build Host:
Comment 5 Brendan Zagaeski (Xamarin Team, assistant) 2014-08-26 14:59:37 UTC
This problem can also appear as the following exception:

> System.NotSupportedException: HttpClientHandler.PreAuthenticate is not supported on this platform.  Please check HttpClientHandler.SupportsPreAuthenticate() before using HttpClientHandler.PreAuthenticate.
>   at System.Net.Http.HttpWebRequest.set_PreAuthenticate (Boolean value) [0x00000] in <filename unknown>:0 
>   at System.Net.Http.HttpClientHandler.SetDefaultOptions (System.Net.Http.HttpWebRequest webRequest) [0x00000] in <filename unknown>:0 
>   at System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest (System.Net.Http.HttpRequestMessage request) [0x00000] in <filename unknown>:0 
>   at System.Net.Http.HttpClientHandler.SendAsync (System.Net.Http.HttpRequestMessage request, CancellationToken cancellationToken) [0x00000] in <filename unknown>:0

The same `app.config` workaround solves that exception too.
Comment 7 mag@xamarin.com 2014-11-06 10:25:26 UTC
Closing this bug as By-Design.

The way that PCL's currently work in the presence of platform specific implementations, requires that the native app also installs the NuGet package.

Here's a good explanation of how PCL's should work in different scenarios, including this particular one: http://blogs.msdn.com/b/dsplaisted/archive/2012/08/27/how-to-make-portable-class-libraries-work-for-you.aspx

The RX assemblies uses the same approach. See the RX team blog post in turn for another case that's very well documented: http://blogs.msdn.com/b/rxteam/archive/2012/08/15/reactive-extensions-v2-0-has-arrived.aspx

Microsoft is aware of this issue, and the plan is to solve this for good in the next version of the platform.
Comment 8 Saurabh 2015-02-09 07:38:15 UTC
As per Comment#7 changing the status to Verified.
Comment 9 Jesse Mock 2015-06-18 19:04:45 UTC
I am having this exact issue with the simplest app ever.  I am simply performing a single POST with httpclient.  I don't see a good descriptive fix here.
Comment 10 Jesse Mock 2015-06-18 19:05:23 UTC
by the way, everything is updated...Xamarin, all Nuget Packages, etc
Comment 11 Brendan Zagaeski (Xamarin Team, assistant) 2015-06-18 20:09:14 UTC
To apply comment 7 to the specific test case that is attached to comment 0, the correct intended way to solve the problem is to install the "Microsoft HTTP Client Libraries" NuGet package into the "HttpAsyncTest" iOS _app project_ in addition to having it installed in the "HttpAsyncLibrary" PCL project.

This is the intended way to use NuGet PCL libraries that contain platform-specific code. (And the "Microsoft HTTP Client Libraries" NuGet _does_ include platform-specific code.)

In case it's helpful as an additional example, ModernHttpClient [1] has this same requirement because it also contains platform-specific code: the NuGet package must be installed into both the PCL library dependencies _and_ the app project that uses the dependencies. (See also [2] for more related discussion.)

[1] https://www.nuget.org/packages/modernhttpclient/
[2] http://log.paulbetts.org/the-bait-and-switch-pcl-trick/