Jonas Stawski

Everything .NET and More

Out of Process Session State and LINQ To SQL Entities

When using ASP.NET you can choose 4 different ways of storing session: In Process, State Server, SQL Server, or Custom. When using In Process the session is stored on the ASP.NET thread of the web server, but when using the State Server or SQL Server the sessions are stored outside the ASP.NET thread. When would you use Out of Process session state? Mostly when you have a web farm and you need to share the same session across all web servers. You might choose to use it even if you have one web server for the simple reason of saving memory on the web server.

When using In Process and you store an object in session, ASP.NET maintains the object in memory and holds a pointer to that object so it can be used on future requests. Based on this explanation you should be able to store almost any object in session, including LINQ to SQL Entities.

The problem arises when you use Out of Process Session State. Whether you use SQL Server or State Server the objects need to be serializable in order to be able to be persisted. The object graph of a LINQ to SQL entity can be very complex and you will need to make every single child entity and type serializable, which can become very cumbersome. I came up with a simple solution that is to serialize all objects when setting them in session and deserialize them when retrieving them from session. In order for this to work you have to make sure that your L2S entities are decorated with the DataContract attribute and the properties are also decorated with the DataMember attribute. If you generate your entities using SqlMetal then you can do so by using the /serialization:Unidirectional parameter or if you use the VS designer by right clicking on the design surface and specify “Uniderectional” in property grid for “Serialization Mode”.

Here are the helper methods:

   1: public static MemoryStream Serialize<T>(T obj)
   2: {
   3:     DataContractSerializer s = new DataContractSerializer(typeof(T));
   4:     MemoryStream ms = new MemoryStream();
   5:     s.WriteObject(ms, obj);
   6:  
   7:     return ms;
   8: }
   9:  
  10: public static T Deserialize<T>(MemoryStream ms)
  11: {
  12:     DataContractSerializer s = new DataContractSerializer(typeof(T));
  13:     ms.Position = 0;
  14:     T retObject = (T)s.ReadObject(ms);
  15:  
  16:     return retObject;
  17: }

A sample on how to use them:

   1: //Store in session
   2: Session["User"] = Serialize(user);
   3:  
   4: //Retrieve from session
   5: User user = Deserialize<User>(Session["User"] as MemoryStream);

Something to be aware of is that by serializing and deserializing a L2S entity you are detaching the entity from the datacontext and hence there will be no lazy loading of child objects nor insertions or updates of that entity. In other words the entity becomes a Plain Old CLR Object (POCO).

Happy Programming!

Comments (6) -

Pure genious!!!
I've tried a number of suggested approaches and neither has worked, until this one.

Reply

You are a freaking genius!!! This helped me out so much! You have made my day. Thank you!

Reply

How does it handle List<User> objects?

Reply

Rodolfo Hernandez
Rodolfo Hernandez

Hey man when i try to do that, send me this error:

Value cannot be null.
Parameter name: fileOrServerOrConnection

what can i do?

Reply

Rahul Patil
Rahul Patil

Hey dude many thanks to you. I tried various methods but none helped. this solved my problem.

Reply

microsoft 365 login portal
United States microsoft 365 login portal

Please, continue posting)

Reply

Add comment

biuquote
Loading