locked
Problem : Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode ... RRS feed

  • Question

  • User-79977429 posted

    Hi

    i've change my webSite sessionState to sqlServer and configure my database to manage sessions, after that, when i login to my site, i'm facing this problem :

    Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode

    Because i'm using dataSet, i've check it (my dataSet designer generated code) and see it marks as Serializable. Where is the problem and how to solve it ?

    Here is btnLogin_Click code which caused the problem :

    protected void btnLogin_Click(object sender, EventArgs e)
            {
                string strUserName = this.txtUserName.Value;
                string strPassword = this.txtPassword.Value;
    
                if (!string.IsNullOrEmpty(strUserName) && !string.IsNullOrEmpty(strPassword))
                {
                    IranHealthDataSet ds = new IranHealthDataSet();
                    IranHealthDataSet.AccountsRow curRow = null;
                    curRow = HelperClass.GetAccountRow(ds.MedicalCenters.TableName, strUserName, strPassword);
    
                    if (curRow != null)
                    {
                        Session["_accountRow"] = curRow;
                        IranHealthDataSetTableAdapters.MedicalCentersTableAdapter medicalCentersTableAdapter = new IranHealthDataSetTableAdapters.MedicalCentersTableAdapter();
                        medicalCentersTableAdapter.Connection.ConnectionString = Singleton.StaticConnectionString;
                        medicalCentersTableAdapter.FillByMedicalCenterRowID(ds.MedicalCenters, Guid.Parse(curRow.OwnerID));
    
                        Singleton.CurrentAccountRowID = ds.MedicalCenters[0]["MedicalCenterRowID"].ToString();
    
                        if (ds.MedicalCenters.Count > 0)
                        {
                            Session["_medicalCenterRow"] = ds.MedicalCenters[0];
                            Response.Redirect("index.aspx");
                        }
                        else
                        {
                            msg.InnerHtml = "<span style='color:red'>Invalid username or password!</span>";
                        }
                    }
                    else
                    {
                        msg.InnerHtml = "<span style='color:red'>Invalid username or password!</span>";
                    }
                }
            }

    And here is my stackTrace of error :

    [SerializationException: Type 'IranHealth.Web.IranHealthDataSet+AccountsRow' in Assembly 'IranHealth.Web, Version=98.3.2.2, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
       System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +12667855
       System.Runtime.Serialization.<>c__DisplayClass9_0.<GetSerializableMembers>b__0(MemberHolder _) +42
       System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory) +73
       System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +186
       System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +166
       System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +187
       System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +53
       System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +571
       System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +137
       System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1644
    
    [HttpException (0x80004005): Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.]
       System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +1733
       System.Web.SessionState.SessionStateItemCollection.WriteValueToStreamWithAssert(Object value, BinaryWriter writer) +36
       System.Web.SessionState.SessionStateItemCollection.Serialize(BinaryWriter writer) +652
       System.Web.SessionState.SessionStateUtility.Serialize(SessionStateStoreData item, Stream stream) +246
       System.Web.SessionState.SessionStateUtility.SerializeStoreData(SessionStateStoreData item, Int32 initialStreamSize, Byte[]& buf, Int32& length, Boolean compressionEnabled) +65
       System.Web.SessionState.SqlSessionStateStore.SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, Object lockId, Boolean newItem) +138
       System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs) +589
       System.Web.SessionState.SessionStateModule.OnEndRequest(Object source, EventArgs eventArgs) +9944900
       System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +144
       System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +50
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +73

    Thanks in advance

    Wednesday, May 29, 2019 11:47 AM

Answers

  • User475983607 posted

    Thanks

    I've marked AccountsRow as serializable :

    [Serializable()]
    public partial class AccountsRow { }

    But again i'm facing anotheer problem :

    [SerializationException: Type 'System.Data.DataRow' in Assembly 'System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.]

    Now, the error is related to DataRow classs!

    Only one record should match the username and password.  Save the DataTable in Session rather than a DataRow.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 29, 2019 5:40 PM

All replies

  • User753101303 posted

    Hi,

    For now the problem seems to happen on your  AccountsRow. You really need to serializable a single DataRow ? IMO you would have to serialize the DataTable that contains this row.

    Also it seems a bit weird to read data from a db and then to have them serialized to SQL Server. IMO :
    - consider the session as a cache and try to store few values you are using very often
    - also I prefer to hide that behind a facade so that it can be reloaded as needed. This way your app doesn't care about session.

    Wednesday, May 29, 2019 12:03 PM
  • User-1038772411 posted

    Hi, Hamed_1983

    when you debug this part of your code and the Linq query has ran. What is the most derived type of GetUserInfo? Another thing you could do is to try to create a custom class, mark it as serializable, copy over the properties you need from what the Linq query returns back, see if all of  these properties are serializable and return that object as a return type. Returning Object or passing in Object is mostly not the way to go.

    Reference Link :

    https://forums.asp.net/t/1355470.aspx?Unable+to+serialize+the+session+state+In+StateServer+and+SQLServer+mode

    Wednesday, May 29, 2019 1:05 PM
  • User475983607 posted

    I recommend a different design approach.  Use a standard authentication cookie to persist the user's Identity.  This will allow you to use ASP.NET's build in authorization framework.   The Session issue goes way because you're not using Session.

    Forms Authentication.

    https://support.microsoft.com/en-us/help/301240/how-to-implement-forms-based-authentication-in-your-asp-net-applicatio

    https://docs.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication?view=netframework-4.8

    Owin Authentication Cookie

    https://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Existing-ASPNET-MVC-Application

    Wednesday, May 29, 2019 1:52 PM
  • User-79977429 posted

    Thanks for reply

    But, because i've used session approach in my whole application, it's very hard to change the approach. So, would you please give a solution base on my approach ?

    Thanks in advance

    Wednesday, May 29, 2019 4:57 PM
  • User475983607 posted

    But, because i've used session approach in my whole application, it's very hard to change the approach. So, would you please give a solution base on my approach ?

    The solution is straight forward, you must use types that can be serialized.  I can only assume IranHealthDataSet.AccountsRow can't be serialized.  You code is custom and therefore  it is up to you to fix your code.  

    Still, I strongly recommend that go with standard security practices.  

    Wednesday, May 29, 2019 5:15 PM
  • User-79977429 posted

    Thanks

    I've marked AccountsRow as serializable :

    [Serializable()]
    public partial class AccountsRow { }

    But again i'm facing anotheer problem :

    [SerializationException: Type 'System.Data.DataRow' in Assembly 'System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.]

    Now, the error is related to DataRow classs!

    Wednesday, May 29, 2019 5:20 PM
  • User475983607 posted

    Thanks

    I've marked AccountsRow as serializable :

    [Serializable()]
    public partial class AccountsRow { }

    But again i'm facing anotheer problem :

    [SerializationException: Type 'System.Data.DataRow' in Assembly 'System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.]

    Now, the error is related to DataRow classs!

    Only one record should match the username and password.  Save the DataTable in Session rather than a DataRow.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 29, 2019 5:40 PM