One way to handle this problem would be to create an IHttpModule that closes your Session. i.e. you don't close your session manually, you let the HttpModule do it for you at the end of each request. I believe this gets run after the web method serializes your objects. I'm using the following code.
This goes in your Web.config file in the <system.web> section.
Code:
<httpModules>
<add name="SessionModule" type="Common.Web.Persistence.SessionModule"/>
</httpModules>
This is the IHttpModule implementation. It assumes you have a helper class that manages your Session. This may not be the best implementation, but, it works for me.
Code:
using Common.Persistence;
using System.Diagnostics;
using System.Web;
using System.Web.SessionState;
namespace Common.Web.Persistence
{
public class SessionModule : IHttpModule
{
private static TraceSource traceSource = new TraceSource("Common",
SourceLevels.All);
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.EndRequest += new System.EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, System.EventArgs e)
{
HttpApplication ha = (HttpApplication)sender;
string path = ha.Request.Path;
if (path.EndsWith(".aspx") || path.EndsWith(".ashx")
|| path.Contains(".asmx"))
{
SessionManager.CloseSession();
}
}
}
}
Another way to do it would be to use NHibernate.NHibernateUtil.Initialize() to initialize the collection before you close your Session manually.
You may also find that you have to set lazy="false" for all classes (not for collections, just classes). Otherwise, Castle.DynamicProxy will generate a proxy class and the proxy class that DynamicProxy generates does not have a no arg constructor and hence can't be XML serialized (I don't know why the authors of DynamicProxy don't just add a no arg constructor).