Reputation: 9630
I have a cache of collection of System.Globalization.CultureInfo class in my Context wrapper class
public Collection<System.Globalization.CultureInfo> Cultures
{
get
{
// Get the value from Redis cache
}
set
{
// Save the value into Redis cache
}
}
It can be accessed via MyContextWrapper.Current.Cultures.
I am getting the following error while serializing the value of "Collection Cultures" with protobuf-net:
Type is not expected, and no contract can be inferred: System.Globalization.CultureInfo
I am aware of the fact that protobuf-net needs [ProtoContract] and [ProtoMember] decoration on class but that is possible only for custom user defined classes.
How can I go with .NET predefined class then for example System.Globalization.CultureInfo in my case.
Is this even possible with protobuf-net?
Upvotes: 2
Views: 4191
Reputation: 1346
You could go with a surrogate. Notify protobuf-net of it before you serialize the Collection. Though what I have now only works with the built-in cultures, you can extend it yourself to add addtional data to fully restore the culture back.
Example
The surrogate to convert CultureInfo into a protobuf-net supported type.
[ProtoContract]
public class CultureInfoSurrogate
{
[ProtoMember(1)]
public int CultureId { get; set; }
public static implicit operator CultureInfoSurrogate(CultureInfo culture)
{
if (culture == null) return null;
var obj = new CultureInfoSurrogate();
obj.CultureId = culture.LCID;
return obj;
}
public static implicit operator CultureInfo(CultureInfoSurrogate surrogate)
{
if (surrogate == null) return null;
return new CultureInfo(surrogate.CultureId);
}
}
Put this somewhere at the start of the program (at least before you are serializing the Collection):
RuntimeTypeModel.Default.Add(typeof(CultureInfo), false).SetSurrogate(typeof(CultureInfoSurrogate));
If you have further questions, let me know in the comments.
Upvotes: 3