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: }




Did you ever get the .ToList() version working?
This issue is so frustrating..
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.)
Hi you mean for List() version, I just change line 46 to
if(!HasClassAttribute( item, typeof(SerializableAttribute), false ) )