/// <summary>
        /// Converts the input dictionary into a dictionary of key to serialized string values
        /// </summary>
        /// <param name="sessionItems">A dictionary some or all of the Session's keys and values</param>
        /// <returns>The serialized version of the input dictionary members</returns>
        public virtual KeyValuePair <RedisValue, RedisValue>[] Serialize(
            List <KeyValuePair <string, object> > sessionItems)
        {
            KeyValuePair <RedisValue, RedisValue>[] serializedItems =
                new KeyValuePair <RedisValue, RedisValue> [sessionItems.Count];

            for (int i = 0; i < sessionItems.Count; i++)
            {
                try
                {
                    serializedItems[i] = new KeyValuePair <RedisValue, RedisValue>(
                        sessionItems[i].Key,
                        this.SerializeOne(
                            sessionItems[i].Key,
                            sessionItems[i].Value));
                }
                catch (Exception e)
                {
                    if (RedisSerializationConfig.SerializerExceptionLoggingDel != null)
                    {
                        RedisSerializationConfig.SerializerExceptionLoggingDel(e);
                    }
                }
            }

            return(serializedItems);
        }
        /// <summary>
        /// Deserializes the entire input of JSON-serialized values into a list of key-object pairs. This
        ///     method is not normally used in RedisSessionProvider, here only for debugging purposes.
        /// </summary>
        /// <param name="redisHashDataRaw">A dictionary of Redis Hash contents, with key being Redis key
        ///     corresponding to Session property and value being a JSON encoded string with type info
        ///     of the original object</param>
        /// <returns>A list of key-object pairs of each entry in the input dictionary</returns>
        public virtual List <KeyValuePair <string, object> > Deserialize(KeyValuePair <RedisValue, RedisValue>[] redisHashDataRaw)
        {
            // process: for each key and value in raw data, convert byte[] field to json string and extract its type property
            //      then deserialize that type and add

            List <KeyValuePair <string, object> > deserializedList = new List <KeyValuePair <string, object> >();

            if (redisHashDataRaw != null)
            {
                foreach (var keyFieldPair in redisHashDataRaw)
                {
                    try
                    {
                        object deserializedObj = this.DeserializeOne(keyFieldPair.Value.ToString());
                        if (deserializedObj != null)
                        {
                            deserializedList.Add(new KeyValuePair <string, object>(
                                                     keyFieldPair.Key.ToString(),
                                                     deserializedObj));
                        }
                    }
                    catch (Exception e)
                    {
                        if (RedisSerializationConfig.SerializerExceptionLoggingDel != null)
                        {
                            RedisSerializationConfig.SerializerExceptionLoggingDel(e);
                        }
                    }
                }
            }

            return(deserializedList);
        }
        /// <summary>
        /// If the key has been deserialized already, return the current object value we have on hand
        ///     for it. If it has not, then deserialize it from initial Redis input and add it to the base
        ///     collection.
        /// </summary>
        /// <param name="key">The desired Session key name</param>
        /// <returns>The deserialized object at the key, or null if it does not exist.</returns>
        protected object MemoizedDeserializeGet(string key)
        {
            object storedObj = null;

            if (this.Items.TryGetValue(key, out storedObj))
            {
                if (storedObj is NotYetDeserializedPlaceholderValue)
                {
                    string serializedData;
                    if (this.SerializedRawData.TryGetValue(key, out serializedData))
                    {
                        try
                        {
                            var placeholderReference = storedObj;
                            storedObj = this.cereal.DeserializeOne(serializedData);

                            // if we can't deserialize, storedObj will still be the placeholder and in that case it's
                            //      as if the DeserializeOne method error'ed, so mark it as failed to deserialize
                            if (storedObj is NotYetDeserializedPlaceholderValue)
                            {
                                storedObj = null;
                            }

                            // Try to update the key to the deserialized object. If it fails, check to make sure that its
                            //      not because it was already deserialized in another thread
                            if (!this.Items.TryUpdate(key, storedObj, placeholderReference))
                            {
                                // the update failed, this could be because the comparison value was different for the
                                //      concurrentDictionary, so lets try fetching the value again
                                if (this.Items.TryGetValue(key, out storedObj))
                                {
                                    // if it is not a placeholder, return the re-fetched object from the Items collection
                                    if (!(storedObj is NotYetDeserializedPlaceholderValue))
                                    {
                                        return(storedObj);
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            if (RedisSerializationConfig.SerializerExceptionLoggingDel != null)
                            {
                                RedisSerializationConfig.SerializerExceptionLoggingDel(e);
                            }

                            storedObj = null;
                        }
                    }
                }
            }

            return(storedObj);
        }
Esempio n. 4
0
        /// <summary>
        /// Deserializes a string containing type and object information back into the original object
        /// </summary>
        /// <param name="objRaw">A string containing type info and JSON object data</param>
        /// <returns>The original object</returns>
        public virtual object DeserializeOne(string objRaw)
        {
            Match fieldTypeMatch = this.typeInfoReg.Match(objRaw);

            if (fieldTypeMatch.Success)
            {
                // if we are deserializing a datatable, use this
                if (fieldTypeMatch.Groups[1].Value == DataTableTypeSerialized)
                {
                    DataSet desDtWrapper = new DataSet();
                    using (StringReader rdr = new StringReader(objRaw.Substring(fieldTypeMatch.Length)))
                    {
                        desDtWrapper.ReadXml(rdr);
                    }
                    return(desDtWrapper.Tables[0]);
                }
                // or if we are doing a dataset
                else if (fieldTypeMatch.Groups[1].Value == DataSetTypeSerialized)
                {
                    DataSet dsOut = new DataSet();
                    using (StringReader rdr = new StringReader(objRaw.Substring(fieldTypeMatch.Length)))
                    {
                        dsOut.ReadXml(rdr);
                    }
                    return(dsOut);
                }
                // or for most things that are sane, use this
                else
                {
                    string typeInfoString = fieldTypeMatch.Groups[1].Value;
                    Type   typeData;

                    if (this.TypeInfoShortcutsDsrlz.ContainsKey(typeInfoString))
                    {
                        typeData = this.TypeInfoShortcutsDsrlz[typeInfoString];
                    }
                    else if (RedisJSONSerializer.TypeCache.TryGetValue(typeInfoString, out typeData))
                    {
                        // great, we have it in cache
                    }
                    else
                    {
                        typeData = JsonConvert.DeserializeObject <Type>(typeInfoString);

                        #region tryCacheTypeInfo
                        try
                        {
                            // we should cache it for future use
                            TypeCache.AddOrUpdate(
                                typeInfoString,
                                typeData,
                                (str, existing) => typeData); // replace with our type data if already exists
                        }
                        catch (Exception cacheExc)
                        {
                            RedisSerializationConfig.SerializerExceptionLoggingDel(
                                new TypeCacheException(
                                    string.Format(
                                        "Unable to cache type info for raw value '{0}' during deserialization",
                                        objRaw),
                                    cacheExc));
                        }
                        #endregion
                    }

                    return(JsonConvert.DeserializeObject(
                               objRaw.Substring(fieldTypeMatch.Length),
                               typeData));
                }
            }
            else
            {
                return(null);
            }
        }