Search code examples
c#asp.net-mvcserializationasp.net-identity

Getting "Unable to serialize the session state" exception while trying to store session data


I am using ASP.NET identity and using cookie middle-ware for authentication and authorization purposes in my ASP.NET MVC application. but I realize that my cookie is getting very long to store in browsers cookie store. So, I decide to store it into a StateServer. To do that I use bellow code in my Startup class

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        SlidingExpiration = true,
        SessionStore = new AspNetAuthSessionStore()
    });

The SessionStore property requires a type of IAuthenticationSessionStore which I found in this link

But I am getting the below error while storing the cookie data

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.

What I see that the implementationIAuthenticationSessionStore.StoreAsync() in the above class AspNetAuthSessionStore having some problen storing the cookie

public Task<string> StoreAsync(AuthenticationTicket ticket)
{
    string key = Guid.NewGuid().ToString();
    HttpContext httpContext = HttpContext.Current;
    CheckSessionAvailable(httpContext);
    httpContext.Session[key + ".Ticket"] = ticket;
    return Task.FromResult(key);
}

I think in line httpContext.Session[key + ".Ticket"] = ticket; the assigned object should be a Serializable object and class AuthenticationTicket is not.

So, how can I solve this problem.


Solution

  • In order to store something in session handled by either StateServer or SQL Server, the object must either be a primitive (string, int, etc.) or be "serializable". Somewhat infuriatingly, that means merely adding a Serializable attribute to the class as Amit suggested in the comments above. Why MVC can't simply serialize a class without this attribute is a bit of a mystery, but that's the way it is.

    If you can't add the Serializable attribute, because as is the case in your situation, you don't control the class, simply, you cannot store that thing in the session, if you want to use StateServer or SQL Server as your session store. You could use in-proc, as that just stores the object in memory, not requiring it to be serialized. However, using StateServer or SQL Server is much better, and switching to the inferior in-proc backing just because of this would be a mistake, I think.

    Now, I'm not sure why you're trying to store this in the session in the first place, but traditionally, the best bet with these types of things is to stick with primitive types. Instead of storing a full object, store an id or similar you can use to fetch that object again. Then, you no longer need to worry about serialization, and you're storing far less data in the session, which is always a good thing.