ASP.NET store Viewstate data in Session

Consider you have a web control as an assembl y and you dont have the source code of this . And the control store its data in viewstate and that data is really big. You can not able to change viewstate usage for this control . And much worse you have to use this important control.Thats may be help you to reduce output and use viewstate process at same time.

I mean you can use viewstate and store in session and reduce the weight of output.Ok that cost as server resources. And I dont really discuss it is proper or efficent or not. I Just show how to do it.

My other article about viewstate deal with compression and how to override base page functions of
LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium
I also use that functions in this article.
http://blog.bugrapostaci.com/2010/02/02/asp-net-compress-viewstate/

We are using one unique session key as path  for each page in session like
 Session[“ViewState_” + this.Request.Path]
You should better if you define a specific Guid value in your pages and use it for Session key.

protected override object LoadPageStateFromPersistenceMedium()
{
    string viewState = string.Empty;
    // try to get state data form Session.
    viewState = Session["ViewState_" + this.Request.Path] != null ? Session["ViewState_"
                      + this.Request.Path].ToString() : string.Empty;
 
    // Decompress the encoded and compressed state data than return it.
    byte[] bytes = Convert.FromBase64String(viewState);
    bytes = Utilities.MemoryCompressor.Decompress(bytes);
    LosFormatter formatter = new LosFormatter();
    return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object state)
{
    //Encode state data
    LosFormatter formatter = new LosFormatter();
    StringWriter writer = new StringWriter();
    formatter.Serialize(writer, state);
    string viewStateString = writer.ToString();
    byte[] bytes = Convert.FromBase64String(viewStateString);
    bytes = Utilities.MemoryCompressor.Compress(bytes);
    //Save to session
    if (Session["ViewState_" + this.Request.Path] != null)
        Session["ViewState_" + this.Request.Path] = Convert.ToBase64String(bytes);
    else
        Session.Add("ViewState_" + this.Request.Path, Convert.ToBase64String(bytes));
}
Happy Codding...

HttpHandler with Session State

If you are developing httphandler in asp.net realized that httphandlers can not use session as default.If you want to access session object do it as below.

Add  “System.Web.SessionState” namespace to your handler code.

There are two interface . one of them  must be inherited by your httphandler object:

IRequiresSessionState Interface

Specifies that the target HTTP handler requires read and write access to session-state values. This is a marker interface and has no methods.

IReadOnlySessionState Interface
Specifies that the target HTTP handler requires only read access to session-state values. This is a marker interface and has no methods.
 
 Example :
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
 
namespace PostmanExamples
{
 
    // IRequireSessionState if you want write access
    public class MyHttpHandlerWithSessionState
        : IHttpHandler, IReadOnlySessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            string s = context.Session["SomeSessionVariable"];
        }
 
        public bools IsReusable { get { return true; } }
    }
}

Session state with web services

 The extra trick needed is on the caller side.  You have to save and store the cookies used by the web service. 

If an XML Web service method uses session state, then a cookie is passed back in the response headers to the XML Web service client that uniquely identifies the session for that XML Web service client. In order for an XML Web service to maintain session state for a client, the client must persist the cookie. Clients can receive the HTTP cookie by creating a new instance of CookieContainer and assigning that to the CookieContainer property of the proxy class before calling the XML Web service method. If you need to maintain session state beyond when the proxy class instance goes out of scope, the client must persist the HTTP cookie between calls to the XML Web service. For instance, a Web Forms client can persist the HTTP cookie by saving the CookieContainer in its own session state. Because not all XML Web services use session state and thus clients are not always required to use theCookieContainer property of a client proxy, the documentation for the XML Web service should state whether session state is used.

See the MSDN documentation on HttpWebClientProtocol.CookieContainer property. 

However, please note if you’re using proxy object to call a web service from your page, the web service and your page cannot share the same session state due to architecture limitation. 

This can be done if you call your web service through redirect. 

Example:

    public class UseWebServiceWithSessionState
    {
        public static void Example()
        {
            // Create a new instance of a proxy class for your XML Web service.
            WebServiceInstance ws = new WebServiceInstance();
            CookieContainer cookieJar;
 
            // Check to see if the cookies have already been saved for this session.
            if (Session["CookieJar"] == null)
                cookieJar = new CookieContainer();
            else
                cookieJar = (CookieContainer)Session["CookieJar"];
 
            // Assign the CookieContainer to the proxy class.
            ws.CookieContainer = cookieJar;
 
            // Invoke an XML Web service method that uses session state and thus cookies.
            int count = ws.PerSessionServiceUsage();
 
            // Store the cookies received in the session state for future retrieval by this session.
            Session["CookieJar"] = cookieJar;
 
            // Populate the text box with the rewslts from the call to the XML Web service method.
            Logger.Log(count.ToString());
        }
 
    }
more info about HttpWebClientProtocol:
http://msdn.microsoft.com/en-us/library/system.web.services.protocols.httpwebclientprotocol(VS.71).aspx

Session_End is not fired

Remarkable Question :
1. Remember Session_End event is supported only in InProc mode.  
2. Session_End won’t be fired if you close your browser. HTTP is a stateless protocol, and the server has no way to know if your browser has closed or not. 
3. Session_End will be fired only (i) after n minutes of inactivity (n = timeout value), or (ii) if someone calls Session.Abandon(). 
4. For case (i) (pt. 3), Session_End will be run by a background thread, which implies:

    a. Your code in Session_End is running using the worker process account. You may have permission problem if you’re accessing resource such as database.
    b. If an error happens in Session_End, it will fail silently.
5. For case (ii), please note that in order for Session_End to be fired, your session state has to exist first.  That means you have to store some data in the session state and has completed at least one request.  
6. Again for case (ii), Session_End will be called only if the abandoned session is actually found. As a result, if you create and abandon a session inside the same request, because the session hasn’t been saved and thus can’t be found, Session_End won’t be called.  This is a bug in v1 and upcoming v1.1.