From 62758ce7f56c0b60b0f88adbe402b3228f8855d3 Mon Sep 17 00:00:00 2001 From: Hailton de Castro Pacheco Barros Date: Fri, 27 Jul 2012 22:06:48 -0300 Subject: [PATCH] Support for serialization of the conversation. Support for serialization of the conversation. Clustering capability for an application that use this "workaround conversation". Previously, the implementation of the "Conversation Workaround" was not capable of serialization. Thus, it was impossible to clustering applications who used this approach. These properties will no longer be loaded by direct injection: "WebConversationManager.SessionFactory", "WebConversationSpringState.SessionFactory" and "WebConversationSpringState.DbProvider". Now we will use this properties: "WebConversationManager.SessionFactoryName", "WebConversationSpringState.SessionFactoryname" and "WebConversationSpringState.DbProviderName". The load of "ISessionfactory" and "IDbProvider" will be made indirectly by classes "WebConversationSpringState" and "WebConversationSpringState". --- .../src/Spring.Northwind.Web.ConvWA/Web.xml | 4 +- .../ConversationWA/IConversationManager.cs | 2 +- .../ConversationWA/IConversationState.cs | 6 +- .../Imple/InnerConversationList.cs | 1 + .../Imple/WebConversationManager.cs | 83 +++++- .../Imple/WebConversationSpringState.cs | 77 +++++- .../Support/SessionPerConversationScope.cs | 1 + .../Support/SessionPerConversationSettings.cs | 1 + .../Spring.ConversationWA.NH32.2008.csproj | 1 - .../SerializeConversationTestModule.cs | 244 ++++++++++++++++++ .../WebConversationStateTest.cs | Bin 65442 -> 68330 bytes .../SerializeConversationTest.aspx | 1 + .../SerializeConversationTest.aspx.cs | 84 ++++++ .../WebConversationStateTest/Web.Config | 4 +- .../services.xml.config | 63 +++-- .../web.config.net-2.0 | 2 + .../Entities/SPCDetailEnt.cs | 1 + .../Entities/SPCMasterEnt.cs | 1 + ...ring.ConversationWA.NH32.Tests.2008.csproj | 1 + .../WebConversationStateTest/Web.Config | 4 +- .../services.xml.config | 65 +++-- .../web.config.net-2.0 | 4 +- ...ring.ConversationWA.NH33.Tests.2008.csproj | 4 +- 23 files changed, 574 insertions(+), 80 deletions(-) create mode 100644 test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/SerializeConversationTestModule.cs create mode 100644 test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/SerializeConversationTest.aspx create mode 100644 test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/SerializeConversationTest.aspx.cs diff --git a/examples/Spring/Spring.Data.NHibernate.Northwind/src/Spring.Northwind.Web.ConvWA/Web.xml b/examples/Spring/Spring.Data.NHibernate.Northwind/src/Spring.Northwind.Web.ConvWA/Web.xml index 250282e9..d067865d 100644 --- a/examples/Spring/Spring.Data.NHibernate.Northwind/src/Spring.Northwind.Web.ConvWA/Web.xml +++ b/examples/Spring/Spring.Data.NHibernate.Northwind/src/Spring.Northwind.Web.ConvWA/Web.xml @@ -29,7 +29,7 @@ - + @@ -102,7 +102,7 @@ - + diff --git a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationManager.cs b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationManager.cs index 5ec3c961..b48ba512 100644 --- a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationManager.cs +++ b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationManager.cs @@ -69,7 +69,7 @@ namespace Spring.ConversationWA /// Must be the same SessionFactory of the managed conversations. /// /// - ISessionFactory SessionFactory { get; set; } + ISessionFactory SessionFactory { get; } /// /// Ends the "paused conversations" in call to . diff --git a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationState.cs b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationState.cs index 2338a910..6e0259c0 100644 --- a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationState.cs +++ b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/IConversationState.cs @@ -141,12 +141,12 @@ namespace Spring.ConversationWA ISession RootSessionPerConversation { get; set; } /// - /// If this is non-null run pattern c. + /// If this is non-null run pattern 'session-per-conversation'. /// It also depends on and . /// must support ConversationManager. /// /// - ISessionFactory SessionFactory { get; set; } + ISessionFactory SessionFactory { get; } /// /// If this is non-null run pattern 'session-per-conversation'. @@ -154,7 +154,7 @@ namespace Spring.ConversationWA /// must support ConversationManager. /// /// - IDbProvider DbProvider { get; set; } + IDbProvider DbProvider { get; } /// /// Indicates that the conversation is paused. diff --git a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/InnerConversationList.cs b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/InnerConversationList.cs index 83ae531b..cbad86ef 100644 --- a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/InnerConversationList.cs +++ b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/InnerConversationList.cs @@ -11,6 +11,7 @@ namespace Spring.ConversationWA.Imple /// List that make validation for Circular Dependence for /// /// Hailton de Castro + [Serializable] public class InnerConversationList: IList, IList { private static readonly ILog LOG = LogManager.GetLogger(typeof(InnerConversationList)); diff --git a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationManager.cs b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationManager.cs index 8fe66e79..7e8c6581 100644 --- a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationManager.cs +++ b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationManager.cs @@ -6,6 +6,8 @@ using System.Web; using Common.Logging; using Spring.Data.NHibernate.Support; using NHibernate; +using Spring.Context; +using Spring.Context.Support; namespace Spring.ConversationWA.Imple { @@ -13,7 +15,8 @@ namespace Spring.ConversationWA.Imple /// This was made to stay under session scope. /// /// Hailton de Castro - public class WebConversationManager : SessionPerConversationScope, IConversationManager + [Serializable] + public class WebConversationManager : SessionPerConversationScope, IConversationManager, IApplicationContextAware { private static readonly ILog LOG = LogManager.GetLogger(typeof(WebConversationManager)); @@ -22,7 +25,18 @@ namespace Spring.ConversationWA.Imple /// /// Semaphore to synchronize writes to the dictionary. /// + [NonSerialized] private Mutex mutexEditDic = new Mutex(); + private Mutex MutexEditDic + { + get + { + if (this.mutexEditDic == null) + this.mutexEditDic = new Mutex(); + return this.mutexEditDic; + } + } + private IDictionary conversations = new Dictionary(); private IConversationState activeConversation = null; @@ -53,7 +67,7 @@ namespace Spring.ConversationWA.Imple try { if (LOG.IsDebugEnabled) LOG.Debug("EndOnTimeOut"); - this.mutexEditDic.WaitOne(5000); + this.MutexEditDic.WaitOne(5000); foreach (String keyItem in this.conversations.Keys) { IConversationState conversationItem = this.conversations[keyItem]; @@ -69,7 +83,7 @@ namespace Spring.ConversationWA.Imple } finally { - this.mutexEditDic.ReleaseMutex(); + this.MutexEditDic.ReleaseMutex(); } } @@ -93,7 +107,7 @@ namespace Spring.ConversationWA.Imple try { if (LOG.IsDebugEnabled) LOG.Debug("EndOnTimeOut"); - this.mutexEditDic.WaitOne(5000); + this.MutexEditDic.WaitOne(5000); List removeList = new List(); foreach (String keyItem in this.conversations.Keys) { @@ -107,7 +121,7 @@ namespace Spring.ConversationWA.Imple if (removeList.Count > 0) { - this.Close(this.sessionFactory, removeList); + this.Close(this.SessionFactory, removeList); } foreach (IConversationState conversationItem in removeList) @@ -119,7 +133,7 @@ namespace Spring.ConversationWA.Imple } finally { - this.mutexEditDic.ReleaseMutex(); + this.MutexEditDic.ReleaseMutex(); } } @@ -131,12 +145,12 @@ namespace Spring.ConversationWA.Imple { try { - this.mutexEditDic.WaitOne(5000); + this.MutexEditDic.WaitOne(5000); this.conversations.Add(conversation.Id, conversation); } finally { - this.mutexEditDic.ReleaseMutex(); + this.MutexEditDic.ReleaseMutex(); } if (conversation.ConversationManager != null && conversation.ConversationManager != this) @@ -231,14 +245,32 @@ namespace Spring.ConversationWA.Imple } } + private String sessionFactoryName; + /// + /// "SessionFactory" name in the current context. + /// This approach is required to support serialization. + /// + public String SessionFactoryName + { + get { return sessionFactoryName; } + set { sessionFactoryName = value; } + } + + [NonSerialized] private ISessionFactory sessionFactory; /// /// /// public ISessionFactory SessionFactory { - get { return sessionFactory; } - set { sessionFactory = value; } + get + { + if (this.sessionFactory == null && this.sessionFactoryName != null) + { + this.sessionFactory = this.ApplicationContext.GetObject(this.sessionFactoryName); + } + return sessionFactory; + } } private bool endPaused = false; @@ -280,7 +312,7 @@ namespace Spring.ConversationWA.Imple { try { - this.mutexEditDic.WaitOne(5000); + this.MutexEditDic.WaitOne(5000); if (!this.conversations.Remove(conversation.Id)) { throw new InvalidOperationException(String.Format("Conversation '{0}' not exists on this manager", conversation.Id)); @@ -288,8 +320,35 @@ namespace Spring.ConversationWA.Imple } finally { - this.mutexEditDic.ReleaseMutex(); + this.MutexEditDic.ReleaseMutex(); } } + + #region IApplicationContextAware Members + private String applicationContextName; + [NonSerialized] + private IApplicationContext applicationContext = null; + /// + /// Returns the current context. Supports serialization and deserialization. + /// + public IApplicationContext ApplicationContext + { + set + { + this.applicationContext = value; + this.applicationContextName = this.applicationContext.Name; + } + get + { + if (this.applicationContext == null) + { + this.applicationContext = ContextRegistry.GetContext(this.applicationContextName); + } + return this.applicationContext; + } + } + + #endregion + } } diff --git a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationSpringState.cs b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationSpringState.cs index 5c91e414..ee586579 100644 --- a/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationSpringState.cs +++ b/src/Spring/Spring.ConversationWA.NH32/ConversationWA/Imple/WebConversationSpringState.cs @@ -15,6 +15,8 @@ using Spring.Data.Common; using NHibernate; using Spring.Data.NHibernate.Support; using Spring.Data.NHibernate; +using Spring.Context; +using Spring.Context.Support; namespace Spring.ConversationWA.Imple { @@ -23,7 +25,8 @@ namespace Spring.ConversationWA.Imple /// It avoid Circular Dependence. /// /// Hailton de Castro - public class WebConversationSpringState : IConversationState, IObjectNameAware + [Serializable] + public class WebConversationSpringState : IConversationState, IObjectNameAware, IApplicationContextAware { private static readonly ILog LOG = LogManager.GetLogger(typeof(WebConversationSpringState)); @@ -276,24 +279,60 @@ namespace Spring.ConversationWA.Imple } } + private String sessionFactoryName; + /// + /// "SessionFactory" name in the current context. + /// This approach is required to support serialization. + /// + public String SessionFactoryName + { + get { return sessionFactoryName; } + set { sessionFactoryName = value; } + } + + [NonSerialized] private ISessionFactory sessionFactory; /// /// /// public ISessionFactory SessionFactory { - get { return sessionFactory; } - set { sessionFactory = value; } + get + { + if (this.sessionFactory == null && this.sessionFactoryName != null) + { + this.sessionFactory = this.ApplicationContext.GetObject(this.sessionFactoryName); + } + return sessionFactory; + } } - IDbProvider dbProvider; + private String dbProviderName; + /// + /// "DbProvider" name in the current context. + /// This approach is required to support serialization. + /// + public String DbProviderName + { + get { return dbProviderName; } + set { dbProviderName = value; } + } + + [NonSerialized] + private IDbProvider dbProvider; /// /// /// public IDbProvider DbProvider { - get { return dbProvider; } - set { dbProvider = value; } + get + { + if (this.dbProvider == null && this.dbProviderName != null) + { + this.dbProvider = this.ApplicationContext.GetObject(this.dbProviderName); + } + return dbProvider; + } } private bool isNew = true; @@ -597,5 +636,31 @@ namespace Spring.ConversationWA.Imple { return base.GetHashCode(); } + + #region IApplicationContextAware Members + private String applicationContextName; + [NonSerialized] + private IApplicationContext applicationContext = null; + /// + /// Returns the current context. Supports serialization and deserialization. + /// + public IApplicationContext ApplicationContext + { + set + { + this.applicationContext = value; + this.applicationContextName = this.applicationContext.Name; + } + get + { + if (this.applicationContext == null) + { + this.applicationContext = ContextRegistry.GetContext(this.applicationContextName); + } + return this.applicationContext; + } + } + + #endregion } } diff --git a/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationScope.cs b/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationScope.cs index bdc15430..969c23a5 100644 --- a/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationScope.cs +++ b/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationScope.cs @@ -42,6 +42,7 @@ namespace Spring.Data.NHibernate.Support /// for dupport to 'session-per-conversation' pattern. /// ///Hailton de Castro + [Serializable] public class SessionPerConversationScope : IDisposable { #region Fields diff --git a/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationSettings.cs b/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationSettings.cs index 68a6f889..85a2c6f0 100644 --- a/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationSettings.cs +++ b/src/Spring/Spring.ConversationWA.NH32/Data/NHibernate/Support/SessionPerConversationSettings.cs @@ -10,6 +10,7 @@ namespace Spring.Data.NHibernate.Support /// Setting for /// /// Hailton de Castro + [Serializable] public class SessionPerConversationScopeSettings { /// diff --git a/src/Spring/Spring.ConversationWA.NH32/Spring.ConversationWA.NH32.2008.csproj b/src/Spring/Spring.ConversationWA.NH32/Spring.ConversationWA.NH32.2008.csproj index 1fca81aa..f922c60f 100644 --- a/src/Spring/Spring.ConversationWA.NH32/Spring.ConversationWA.NH32.2008.csproj +++ b/src/Spring/Spring.ConversationWA.NH32/Spring.ConversationWA.NH32.2008.csproj @@ -73,7 +73,6 @@ nant.xsd - diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/SerializeConversationTestModule.cs b/test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/SerializeConversationTestModule.cs new file mode 100644 index 00000000..104ba954 --- /dev/null +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/SerializeConversationTestModule.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; +using System.Runtime.Remoting.Messaging; +using System.Runtime.Serialization; +using System.Reflection; +using Spring.Entities; + +namespace Spring.ConversationWA +{ + /// + /// Module that forces the serialization and deserialization of the session content to simulate a clustered server for + /// . + /// + public class SerializeConversationTestModule: IHttpModule + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SerializeConversationTestModule)); + + #endregion + + /// + /// Serialized Session Content. + /// + private static MemoryStream SerializedSessionContentStream = new MemoryStream(); + + #region IHttpModule Members + + /// + /// TODO: + /// + public void Dispose() + { + // + } + + /// + /// TODO: + /// + /// + public void Init(HttpApplication context) + { + context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); + context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute); + } + + /// + /// Repopulates the session from the previously serialized content. + /// + /// + /// + void context_PreRequestHandlerExecute(object sender, EventArgs e) + { + if (HttpContext.Current.Session != null) + { + if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath == "~/SerializeConversationTest.aspx") + { + if (SerializedSessionContentStream.Length > 0) + { + BinaryFormatter bf = new BinaryFormatter(); + bf.Binder = new MyBinder(); + //SurrogateSelector surrogateSelector = new SurrogateSelector(); + //surrogateSelector.AddSurrogate( + // typeof(Object), + // new StreamingContext(StreamingContextStates.All), + // new MySerializationSurrogate()); + //bf.SurrogateSelector = surrogateSelector; + + SerializedSessionContentStream.Seek(0, SeekOrigin.Begin); + Dictionary sessionConttent = + (Dictionary)bf.Deserialize(SerializedSessionContentStream); + + HttpContext.Current.Session.Clear(); + foreach (String keyItem in sessionConttent.Keys) + { + HttpContext.Current.Session[keyItem] = sessionConttent[keyItem]; + } + } + } + } + } + + /// + /// Serializes and clears the session. + /// + /// + /// + void context_PostRequestHandlerExecute(object sender, EventArgs e) + { + if (HttpContext.Current.Session != null) + { + //NHibernate.ISession ss; + if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath == "~/SerializeConversationTest.aspx") + { + Dictionary sessionConttent = new Dictionary(); + foreach (String keyItem in HttpContext.Current.Session.Keys) + { + sessionConttent[keyItem] = HttpContext.Current.Session[keyItem]; + } + + BinaryFormatter bf = new BinaryFormatter(); + bf.Binder = new MyBinder(); + //SurrogateSelector surrogateSelector = new SurrogateSelector(); + //surrogateSelector.AddSurrogate( + // typeof(Object), + // new StreamingContext(StreamingContextStates.All), + // new MySerializationSurrogate()); + //bf.SurrogateSelector = surrogateSelector; + + SerializedSessionContentStream = new MemoryStream(); + bf.Serialize(SerializedSessionContentStream, sessionConttent); + + HttpContext.Current.Session.Clear(); + } + } + } + #endregion + } + + public class MyBinder : SerializationBinder + { + #region Logging + + private Common.Logging.ILog LOG + { + get + { + return Common.Logging.LogManager.GetLogger(typeof(SerializeConversationTestModule)); + } + } + + #endregion + + public override Type BindToType(string assemblyName, string typeName) + { + if (LOG.IsDebugEnabled) + LOG.Debug(String.Format("MyBinder.BindToType: {0}, {1}", typeName, assemblyName)); + return Type.GetType(typeName + ", " + assemblyName); + } + } + + ///// + ///// For debugging purpose. + ///// + //public class MySurrogateSelectorWrapper : ISurrogateSelector + //{ + + // ISurrogateSelector wrapped; + // public MySurrogateSelectorWrapper(ISurrogateSelector wrapped) + // { + // this.wrapped = wrapped; + // } + // #region ISurrogateSelector Members + + // public void ChainSelector(ISurrogateSelector selector) + // { + // this.wrapped.ChainSelector(selector); + // } + + // public ISurrogateSelector GetNextSelector() + // { + // ISurrogateSelector selector = this.wrapped.GetNextSelector(); + // if (!(selector is MySurrogateSelectorWrapper)) + // selector = new MySurrogateSelectorWrapper(selector); + // return selector; + // } + + // public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) + // { + // ISerializationSurrogate surrogate = new MySerializationSurrogate(this.wrapped.GetSurrogate(type, context, out selector)); + // if (!(selector is MySurrogateSelectorWrapper)) + // selector = new MySurrogateSelectorWrapper(selector); + // return surrogate; + // } + + // #endregion + //} + + /// + /// For debugging purpose. + /// + public class MySerializationSurrogate : ISerializationSurrogate + { + #region Logging + + private static readonly Common.Logging.ILog LOG = Common.Logging.LogManager.GetLogger(typeof(SerializeConversationTestModule)); + + #endregion + public MySerializationSurrogate() + { + } + + #region ISerializationSurrogate Members + + public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) + { + if (LOG.IsDebugEnabled) + LOG.Debug(String.Format("MySerializationSurrogateWrapper.GetObjectData({0},...", obj.GetType())); + + FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + if (obj is ISerializable) + { + ((ISerializable)obj).GetObjectData(info, context); + } + else + { + for (int i = 0; i < fields.Length; i++) + { + if ((fields[i].Attributes & FieldAttributes.NotSerialized) == 0) + { + info.AddValue(fields[i].Name, fields[i].GetValue(obj), fields[i].FieldType); + } + } + } + } + + public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) + { + if (LOG.IsDebugEnabled) + LOG.Debug(String.Format("MySerializationSurrogateWrapper.SetObjectData({0},...", obj.GetType())); + + FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + + for (int i = 0; i < fields.Length; i++) + { + if ((fields[i].Attributes & FieldAttributes.NotSerialized) == 0) + { + fields[i].SetValue(obj, info.GetValue(fields[i].Name, fields[i].FieldType)); + } + } + if (obj is IDeserializationCallback) + ((IDeserializationCallback)obj).OnDeserialization(obj); + + return obj; + } + + #endregion + } +} diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/WebConversationStateTest.cs b/test/Spring/Spring.ConversationWA.NH32.Tests/ConversationWA/WebConversationStateTest.cs index 5e46f89ad5fab8e55a71f9932ec84fe19424c9ab..d4654295adfa8f464a50684ee6e805abb5853548 100644 GIT binary patch delta 617 zcmZ4VpZV2PmJJ?%CmVz*OW3u0Whsg_gL?$P2a7_*fHsDQVC}PNDNMy(Xl2wx*s!LD)Aj+{>id%<~KbQfl z!}8{=dH4i@_~pt(g1#SA433P7C6kP9?afkA^I2}q|g|sxik9>20u1ROmV{iqAXAzKH1Poyu?gy$0W+(-Qe+f`kBG4Zt(Aa?c NfAYaL#mRmDMF2B*zySaN delta 82 zcmaDgm1WU?<_#Wy*)ti^7!(*ZCNC^> \ No newline at end of file diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/SerializeConversationTest.aspx.cs b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/SerializeConversationTest.aspx.cs new file mode 100644 index 00000000..60e92369 --- /dev/null +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/SerializeConversationTest.aspx.cs @@ -0,0 +1,84 @@ +using System; +using System.Data; +using System.Configuration; +using System.Collections; +using System.Web; +using System.Web.Security; +using System.Web.UI; +using System.Web.UI.WebControls; +using System.Web.UI.WebControls.WebParts; +using System.Web.UI.HtmlControls; +using Spring.ConversationWA; +using Spring.Data.NHibernate.Support; +using NHibernate; +using Spring.Entities; +using Spring.Spring.Data.Common; +using NUnit.Framework; +using Spring.Bsn; +using NHibernate.Impl; +using System.Reflection; +using NHibernate.Cfg; +using Spring.Context; +using System.Collections.Generic; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; + +/// +/// Page for . +/// +public partial class SerializeConversationTest : System.Web.UI.Page +{ + private IConversationState conversation; + /// + /// + /// + public IConversationState Conversation + { + get { return conversation; } + set { conversation = value; } + } + + protected void Page_Load(object sender, EventArgs e) + { + try + { + this.Conversation.StartResumeConversation(); + ISession ss = this.Conversation.SessionFactory.GetCurrentSession(); + IList deatilList = ss.CreateCriteria().List(); + + this.Conversation.ConversationManager.PauseConversations(); + + BinaryFormatter bf = new BinaryFormatter(); + MemoryStream ms = new MemoryStream(); + + System.Collections.ArrayList sessionContent = new System.Collections.ArrayList(); + foreach (String keyItem in this.Session.Keys) + { + sessionContent.Add(this.Session[keyItem]); + } + + bf.Serialize(ms, sessionContent); + + + if (this.Session["SPCDetailEnt#1"] == null) + { + //at the first time + this.Session["SPCDetailEnt#1"] = ss.Get(1); + } + else + { + //at the second time + if (!Object.ReferenceEquals(this.Session["SPCDetailEnt#1"], ss.Get(1))) + throw new InvalidOperationException("!Object.ReferenceEquals(this.Session['SPCDetailEnt#1'], ss.Get(1))"); + } + + Response.Clear(); + Response.Write("OK"); + } + catch (Exception ex) + { + Response.Clear(); + Response.Write(ex.Message + " " + ex.StackTrace); + } + } +} diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config index d8db7f1e..e9405818 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config @@ -30,7 +30,7 @@ - + @@ -48,6 +48,7 @@ + @@ -62,6 +63,7 @@ + diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config index 61ae00aa..f9452f87 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config @@ -3,7 +3,7 @@ xmlns:db="http://www.springframework.net/database" xmlns:tx="http://www.springframework.net/tx"> - + @@ -116,7 +116,7 @@ - + @@ -151,8 +151,8 @@ - - + + @@ -164,15 +164,15 @@ - - + + - - + + @@ -184,8 +184,8 @@ - - + + @@ -201,8 +201,8 @@ - - + + @@ -242,15 +242,15 @@ - - + + - - + + @@ -265,18 +265,18 @@ - - + + - - + + - + @@ -291,17 +291,30 @@ - - + + - + + + + + + + + + + + + + + - + diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 index 47c16f16..d311c5de 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 @@ -48,6 +48,7 @@ + @@ -62,6 +63,7 @@ + diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCDetailEnt.cs b/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCDetailEnt.cs index 28666448..3070a489 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCDetailEnt.cs +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCDetailEnt.cs @@ -11,6 +11,7 @@ namespace Spring.Entities /// /// /// Hailton de Castro + [Serializable] public class SPCDetailEnt { private Int32? id; diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCMasterEnt.cs b/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCMasterEnt.cs index 7e50db53..76411178 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCMasterEnt.cs +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Entities/SPCMasterEnt.cs @@ -11,6 +11,7 @@ namespace Spring.Entities /// /// /// Hailton de Castro + [Serializable] public class SPCMasterEnt { private Int32? id; diff --git a/test/Spring/Spring.ConversationWA.NH32.Tests/Spring.ConversationWA.NH32.Tests.2008.csproj b/test/Spring/Spring.ConversationWA.NH32.Tests/Spring.ConversationWA.NH32.Tests.2008.csproj index 81beef06..3a8a419d 100644 --- a/test/Spring/Spring.ConversationWA.NH32.Tests/Spring.ConversationWA.NH32.Tests.2008.csproj +++ b/test/Spring/Spring.ConversationWA.NH32.Tests/Spring.ConversationWA.NH32.Tests.2008.csproj @@ -82,6 +82,7 @@ ASPXCodeBehind + diff --git a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config index b84471fd..f154858a 100644 --- a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config +++ b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/Web.Config @@ -30,7 +30,7 @@ - + @@ -48,6 +48,7 @@ + @@ -62,6 +63,7 @@ + diff --git a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config index d7172cf3..dbff9f29 100644 --- a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config +++ b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/services.xml.config @@ -2,8 +2,8 @@ - - + + @@ -116,7 +116,7 @@ - + @@ -151,8 +151,8 @@ - - + + @@ -164,15 +164,15 @@ - - + + - - + + @@ -184,8 +184,8 @@ - - + + @@ -201,8 +201,8 @@ - - + + @@ -242,15 +242,15 @@ - - + + - - + + @@ -265,18 +265,18 @@ - - + + - - + + - + @@ -291,17 +291,30 @@ - - + + - + + + + + + + + + + + + + + - + diff --git a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 index b84471fd..f154858a 100644 --- a/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 +++ b/test/Spring/Spring.ConversationWA.NH33.Tests/Data/Spring/ConversationWA/WebConversationStateTest/web.config.net-2.0 @@ -30,7 +30,7 @@ - + @@ -48,6 +48,7 @@ + @@ -62,6 +63,7 @@ + diff --git a/test/Spring/Spring.ConversationWA.NH33.Tests/Spring.ConversationWA.NH33.Tests.2008.csproj b/test/Spring/Spring.ConversationWA.NH33.Tests/Spring.ConversationWA.NH33.Tests.2008.csproj index 3c2a9d1f..da20b1c6 100644 --- a/test/Spring/Spring.ConversationWA.NH33.Tests/Spring.ConversationWA.NH33.Tests.2008.csproj +++ b/test/Spring/Spring.ConversationWA.NH33.Tests/Spring.ConversationWA.NH33.Tests.2008.csproj @@ -97,6 +97,9 @@ ConversationWA\PatialEndConvEndBasePage.cs ASPXCodeBehind + + ConversationWA\SerializeConversationTestModule.cs + ConversationWA\WebConversationStateTest.cs @@ -138,7 +141,6 @@ -