c# - How to convert session data to SessionStateStoreData type in custom session state provider -
i using custom session provider in web application inheriting sessionstatestoreproviderbase , overriding methods. method used getting data session has return type of sessionstatestoredata.
currently binary serialization being used serializing , deserializing data. want use json serialization instead of binary not sure how convert session data (of type string after json serialization) sessionstatestoredata type. constructor of sessionstatestoredata type uses sessionstateitemcollection type object can deserialize method of sessionstateitemcollection takes binary stream input.
var ms = _serializedsessiondata == null ? new memorystream() : new memorystream(_serializedsessiondata); var sessionitems = new sessionstateitemcollection(); if (ms.length > 0) { var reader = new binaryreader(ms); sessionitems = sessionstateitemcollection.deserialize(reader); } return new sessionstatestoredata(sessionitems, sessionstateutility.getsessionstaticobjects(context), _timeout);
i have attached code used binary deserialization. how same thing json serialized object?
a sessionstateitemcollection
close dictionary<string, object>
, serialize such. however, need account possibility of null
key. null
key allowed sessionstateitemcollection
dictionary<string, object>
throw exception on null key.
since values in sessionstateitemcollection
untyped, need json serializer supports serializing of type information of arbitrary types. json.net can this. javascriptserializer
can well. datacontractjsonserializer
not appropriate since must know possible types in advance , pass them constructor known types.
for remainder of answer i'll assume have chosen json.net.
first, define following intermediate class serialization:
public class stringdictionarywrapper { public stringdictionarywrapper() { items = new dictionary<string, object>(); } // holds value of item null key, if any. [jsonproperty(itemtypenamehandling = typenamehandling.auto, defaultvaluehandling = defaultvaluehandling.ignore)] public object nullitem { get; set; } [jsonproperty(itemtypenamehandling = typenamehandling.auto)] public dictionary<string, object> items { get; set; } }
then, serialize sessionstateitemcollection
json string, do:
var dict = new stringdictionarywrapper { items = sessionitems.keys.oftype<string>().todictionary(key => key, key => sessionitems[key]), nullitem = sessionitems[null] }; var json = jsonconvert.serializeobject(dict, formatting.indented);
the json like:
{ "nullitem": 1123, "items": { "foo": { "$type": "question30640792.someclass, tile", "someproperty": "foo2" }, "testclass": { "$type": "question30640792.testclass, tile", "a": 101, "b": 102 } } }
to deserialize json string, do:
var sessionitems = new sessionstateitemcollection(); var dict = jsonconvert.deserializeobject<stringdictionarywrapper>(json); if (dict != null && dict.nullitem != null) sessionitems[null] = dict.nullitem; if (dict != null && dict.items != null) foreach (var pair in dict.items) sessionitems[pair.key] = pair.value;
note deserialize entire collection of session state items @ once, whereas built-in binary serialization uses on-demand deserialization performance reasons. might see performance hit. also, since dictionary<tkey, tvalue>
unordered, session items may not come in same order originally. if that's problem, may need create custom proxy wrapper session item collection.
Comments
Post a Comment