Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
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
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 or GitHub 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.
Created attachment 11299 [details]
After updating to XI 8.10 from 8.8, deserializing CookieContainer fails with an exception.
**Steps to Reproduce:**
1. Install XI 126.96.36.199
2. Run the attached sample on a simulator. An alert will show a success.
3. Kill, and run the app again on the simulator. Another alert will show that the cookie was loaded.
4. Install XI 8.10+
5. Run the app again.
Unexpected binary element: 9 (System.Runtime.Serialization.SerializationException)
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) [0x00189] in /Users/builder/data/lanes/1799/3c4e832a/source/mono/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:250
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (System.IO.BinaryReader reader) [0x00027] in /Users/builder/data/lanes/1799/3c4e832a/source/mono/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:150
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header& headers) [0x0004d] in /Users/builder/data/lanes/1799/3c4e832a/source/mono/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:107
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x0007a] in /Users/builder/data/lanes/1799/3c4e832a/source/mono/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:177
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) [0x00000] in /Users/builder/data/lanes/1799/3c4e832a/source/mono/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:134
at CookieTest.AppDelegate.FinishedLaunching (UIKit.UIApplication application, Foundation.NSDictionary launchOptions) [0x0002f] in /Users/johnmiller/Downloads/CookieTest/AppDelegate.cs:42
at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string,intptr,intptr)
at UIKit.UIApplication.Main (System.String args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/1799/3c4e832a/source/maccore/src/UIKit/UIApplication.cs:63
at UIKit.UIApplication.Main (System.String args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/1799/3c4e832a/source/maccore/src/UIKit/UIApplication.cs:47
at CookieTest.Application.Main (System.String args) [0x00008] in /Users/johnmiller/Downloads/CookieTest/Main.cs:12
No exceptions. The same alert from step #3 should work.
**Build Date & Platform:**
Maybe something changed in the serialization/CookieContainer between the XI versions
XI 8.8 was based on Mono 3.12
XI 8.10 was based on Mono 4.0
Mono 4.0 includes quite a bit of Microsoft's .NET reference sources  in it's class libraries which, in turn, is used for what XI (and other Xamarin products) ships.
That's good news for compatibility with MS .NET but it also means some internals do change (it's the only way to gain that increased compatibility).
In this case the (undocumented) internals of CookieContainer changed and that broke the binary serialization of that type.
A strategy to workaround this would be to have the application:
1. load the serialized data;
2. catch the exception, if there's any
2.1 re-create the data and re-serialize it with the new format
3. continue execution
Alternatively use another mechanism to serialize your data, one that does not depend on the internals of the types.
 work in progress, but CookieContainer was done in 4.0 mcs/class/System/System.dll.sources:../../../external/referencesource/System/net/System/Net/cookiecontainer.cs
Thanks for looking into this. Pretty much what I expected. Unfortunately the suggested strategy has some problems:
1. An exception is not always thrown when loading the data. Sometimes it throws an exception, sometimes it loads but causes a later exception when accessing the cookie container and sometimes it loads but ends up empty.
2. Re-creating the data is not necessarily as simple as implied. In our case we're storing a login cookie from our server. To recreate that requires the user to login again - not a good user experience and may require unwinding the user-interface stack.
3. It makes no guarantees that we're not going to be bitten by this again - which makes the whole point of a serializable cookie container pointless.
4. I'd like to build my own serialization of CookieContainer but it's contents can't be enumerated - making that impossible.
5. The Cookie class can't be fully serialized externally because it has read-only properties (TimeStamp comes to mind) which are serialized by the built in serialization yet can't be externally serialized
In short I understand the reason for the change, but to have the rug pulled out from under what was previously reliable working code, with no real workable solution has left me quite disappointed with Xamarin's approach.
1/2. You can try to access the data and determine if it makes sense. That should trigger an exception or give you something empty. Not ideal but it's something you can trigger on...
3. It could happen on other types, but it's unlikely to happen again on CookieContainer. Matching MS implementation is a one way trip (and MS, like mono, does it best not to change format needlessly);
4/5. You might want to try reflection (to serialize the data). Also you could manually deserializing the data, but it's a more complex approach
Switching to MS reference sources has a lot of advantages but sadly, like you found out, there are some inconveniences too :(