Storing LINQ Objects in SQL-Based Session State

// January 30th, 2008 // LINQ

Scott Hanselman recently posted about various options you have for session storage while using ASP.Net. In the comments of his post I brough up an issue I recently encountered at work (where we use SQL Server session state):

LINQ-To-Sql generated objects are not marked [Serializable] and cannot be stored in out-of-process session storage.

To get around this I have whipped up the following helper class which will serialize LINQ-To-Sql objects if you set the DataContext's Serializable property to "Unidirectional".

Note: The following class does not current work for storing List<X> where X is a LINQ-To-Sql object. I'll be working to resolve that sometime later this week.

   1: using System;
   2: using System.IO;
   3: using System.Runtime.Serialization;
   4: using System.Text;
   5: using System.Xml;
   6: using System.Web;
   7: 
   8: namespace SquaredRoot.Helper
   9: {
  10:   public class SessionHelper
  11:   {
  12: 
  13:     private SessionHelper(){}
  14: 
  15:         public static T Get<T>( string key ) where T : class
  16:         {
  17: 
  18:             object o = HttpContext.Current.Session[key];
  19:             if( o == null )
  20:                 return default( T );
  21: 
  22:             if( o.GetType() == typeof( string ) && typeof( T ) != typeof( string ) )
  23:             {
  24:                 string s = o as string;
  25:                 Stream stream = new MemoryStream( Encoding.Unicode.GetBytes(s) );
  26:                 XmlDictionaryReader xml = XmlDictionaryReader.CreateTextReader( stream, new XmlDictionaryReaderQuotas() );
  27:                 DataContractSerializer dcs = new DataContractSerializer( typeof( T ) );
  28:                 T t = (T)dcs.ReadObject( xml, true );
  29:                 xml.Close();
  30:                 return t;
  31:             }
  32:             else
  33:                 return o as T;
  34: 
  35:         }
  36: 
  37:         private static bool HasClassAttribute( object o, Type attribute, bool inherit )
  38:         {
  39:             return ( o.GetType().GetCustomAttributes( attribute, inherit ).Length > 0 );
  40:         }
  41: 
  42:         public static void Set( string key, object item )
  43:         {
  44: 
  45:             object value = item;
  46:             if( HasClassAttribute( item, typeof(DataContractAttribute), false )
  47:         && !HasClassAttribute( item, typeof(SerializableAttribute), false ) )
  48:             {
  49:                 DataContractSerializer dcs = new DataContractSerializer(item.GetType());
  50:                 StringBuilder sb = new StringBuilder();
  51:                 XmlWriter writer = XmlWriter.Create(sb);
  52:                 dcs.WriteObject( writer, item );
  53:                 writer.Close();
  54:                 value = sb.ToString();
  55:             }
  56: 
  57:             if( HttpContext.Current.Session[key] == null )
  58:         HttpContext.Current.Session.Add( key, value );
  59:             else
  60:         HttpContext.Current.Session[key] = value;
  61: 
  62:         }
  63: 
  64:     }
  65: }
Kick It on DotNetKicks.comShout It on DotNetShoutOuts.com

3 Responses to “Storing LINQ Objects in SQL-Based Session State”

  1. Nicholas says:

    Did you ever get the .ToList() version working?

    This issue is so frustrating..

  2. Kevin Read says:

    To get the .ToList() version working, all I did was to remove the check for the DataContractAttribute on the item. (Line 46 on the code example above.)

  3. Patrick says:

    Hi you mean for List() version, I just change line 46 to

    if(!HasClassAttribute( item, typeof(SerializableAttribute), false ) )