Runtime: How can I use binary serialization with CookieContainer

Created on 30 Apr 2017  路  10Comments  路  Source: dotnet/runtime

I need to serialize CookieContainer to the binary file. I was looking for BinaryFormatter but couldn't find it. I use the newest version of .NET Core. I tried serializing it with protobuf-net and msgpack but it didn't work. Any solution for this? I saw the support for binary serialization was added in 2.0 but I need to use some alternative solution now in 1.1.

area-System.Net bug

Most helpful comment

@midnightstarr I appreciate your frustration and agree that the cookie* classes don't have a lot of public API surface to approximate a serialization solution.

Unfortunately, for .NET Core 1.x, there is no good solution other than reflection. I believe that .NET Core 2.0 will provide better serialization support.

All 10 comments

In general .NET Core 1.x does not support binary serialization. This is only supported in .NET Core 2.0.

You can always implement something custom via XML/Json, etc. but that requires you to hand serialize the objects using only the public API surfaces (properties, etc.).

cc: @karelz @danmosemsft

Although we have binary serialization in 2.0, we are planning to scale it back before we ship to just primitive and collection types (https://github.com/dotnet/corefx/issues/19119). For higher types like this we recommend using a different serializer.

CookieContainer exposes too little to serialize it all and without using reflection and accessing _domainTable it's not possible to get all the cookies without specifying the Uri. So at the moment, this kind of hacks are required.

Also, the Add method requires Uri to be given as compared to .NET Framework https://msdn.microsoft.com/pl-pl/library/system.net.cookiecontainer(v=vs.110).aspx there is also Add for just a Cookie and just CookieCollection without a need for a Uri.

```c#
public static IEnumerable GetCookies(this CookieContainer cookieContainer)
{
var domainTable = GetFieldValue(cookieContainer, "_domainTable");
foreach(var entry in domainTable)
{
string key = GetPropertyValue(entry, "Key");

    var value = GetPropertyValue<dynamic>(entry, "Value");

    var internalList = GetFieldValue<SortedList<string,CookieCollection>>(value, "_list");
    foreach(var li in internalList) 
    {
        foreach(Cookie cookie in li.Value) 
    {
            yield return cookie;
        }
    }
}

}

internal static T GetFieldValue(object instance, string fieldName)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
FieldInfo fi = instance.GetType().GetField(fieldName, bindFlags);
return (T)fi.GetValue(instance);
}

internal static T GetPropertyValue(object instance, string propertyName)
{
var pi = instance.GetType().GetProperty(propertyName);
return (T)pi.GetValue(instance, null);
}
```

@midnightstarr I appreciate your frustration and agree that the cookie* classes don't have a lot of public API surface to approximate a serialization solution.

Unfortunately, for .NET Core 1.x, there is no good solution other than reflection. I believe that .NET Core 2.0 will provide better serialization support.

With 2.0 we are adding serialization support for CookieContainer!

With 2.0 we are adding serialization support for CookieContainer!

Are we sure? Based on this https://github.com/dotnet/corefx/pull/19742, I'm not so sure.

I'm sure :) I did it myself ;)

https://github.com/dotnet/corefx/pull/20247

This should be the correct list of the types we preserved [Serializable] on: https://gist.github.com/morganbr/2a9901b12f1d342285694e69983a12d0 (minus Lazy)

I'm sure :) I did it myself ;)

@ViktorHofer Thanks!

Was this page helpful?
0 / 5 - 0 ratings