Serializing Custom .Net Types for use with the Azure Redis Cache

In my previous post I looked at a real-world example of using the new Azure Redis Cache. One thing that was missing was the storing of custom .Net Types as cache values, which we’ll look at here.

The RedisValue Type

The Microsoft Azure documentation recommends using the StackExchange.Redis API for accessing the Redis Cache. This API stores cache values within the RedisValue type, which has a number of implcit conversions from primitive .Net types (Int32, Int64, Double, Boolean etc.), but conversions from the RedisValue type to the primitive .Net type need to be made explicitily.

For example, setting an int as the cache value is implicit, while retrieving an int from a cache value needs to be cast (the following screenshot is from the MSDN documentation):

Cache Serializer - Get and Set of Primitive Types

In addition to the implicit/explicit conversion of primitive data types, the RedisValue type can store binary data as the cache value. This means that we can serialize a custom .Net type into a byte array and pass that as the cache value within the StringSet() method; we can then retrieve that cache value using the StringGet() method and deserialize the byte array back to the custom type.

To complete the serialization/deserialization, we need a helper class, which is shown below. This class is inspired by the sample on MSDN (Work with .Net objects in the cache) but is tweaked slightly:

Note that during deserialization, if the byte array is null, a default instance of type T will be returned. This caught me out when I was initially testing, so beware that it is returning the value you expect.

Using these helpers with the StackExchange.Redis API’s StringSet() and StringGet() methods to store custom .Net types makes life really easy:

To retrieve a custom type, we call the StringGet() method, passing the cache Key and deserialize the returned byte array into the .Net Guid type; In order to determine whether the cache item was found, I check whether the returned cacheItem equals Guid.Empty, which is the value returned by default(T) for the Guid type from the Deserialize() method.

To store a custom .Net type (in this case a GUID), call the StringSet() method and instead of passing a primitive type as the cache value, we serialize our cache item and pass the resulting byte array.

Advertisements

Failed to Serialize the Message Part, Ensure that the Message Part Stream is Created Properly

Encountered the following error today on a SOAP [Send] Port:

Failed to serialize the message part “[PART NAME]” into the type “[MESSAGE TYPE]” using namespace “[NAMESPACE]”. Please ensure that the message part stream is created properly.

The error is a little misleading, especially ‘ensure that the message part stream is created properly‘ – the message part stream is created correctly, but it does not match the type contained within the SOAP adapter proxy and therefore fails to serialize. In our case, we were trying to serialize an element with the string ‘Stan’ into a boolean. With the best will in the world, that isn’t going to happen!

To check where the problem lies with serialization, simply validate the failed message (retrieved from the Admin Console) against the schema generated from the WSDL, using the Visual Studio ‘Validate Instance‘ schema menu option. You’ll be presented with a list of errors that can then be resolved.

Our problems went a lot further and resulted in a fairly impressive hacky bodge that I am extremely proud of, especially on a Friday at 5pm (with a Bank Holiday weekend waiting for me). I’ll spare you that for another post!