Results 1 to 4 of 4

Thread: HttpState for asp.net, C# and SQL

  1. #1
    Ext JS Premium Member
    Join Date
    Sep 2008
    Posts
    38

    Default HttpState for asp.net, C# and SQL

    Hi, I just wanted to post my code as a starting point for anyone who wants to use the wonderful HttpState provider. I know i banged my head around as a newbie trying to wrap my head around the power of ExtJs and not being able to find a good example of this. Hopefully this will help someone get started. This example is for using Saki's Ext.ux.HttpProvider with ASP.NET, C# and a MSSQL backend. I just whipped this up with a little bit of quickness, so let me know if it needs modification or further clarification.

    I recommend using your own stateId in the components that you want state enabled on... without it, there is no guarantee that the auto id generator will produce the same results... especially if you changed your app around.

    If enough people ask for it, i can put together a working example.

    Enjoy!

    Some assumptions:
    • this example assumes that Membership is in use and this page is protected. meaning that someone has signed in already. you should be able to easily port this over to anonymous with a little tweaking
    • this assumes some general working knowledge of both ASP.NET and ExtJS
    • this is a simple uncomplicated example and only handles a single element's state being saved (ie. if 2 element's state are being saved in one request, it will break. a few simple changes can remedy this.




    What you'll end up with.
    • A new table named SessionState
    • A new stored procedure named rsp_SessionState_Save
    • An .aspx page with a code-behind
    • An .ashx generic handler page



    The following is a listing of all the code. There are several ways to implement, so i simplified just to make it easy


    Create the table
    Code:
    CREATE TABLE [dbo].[SessionState](
    	[UserId] [uniqueidentifier] NOT NULL,
    	[Name] [varchar](128) NOT NULL,
    	[Value] [varchar](8000) NOT NULL,
    	[DateUpdated] [datetime] NOT NULL DEFAULT(getDate())
    ) ON [PRIMARY]

    Create the stored proc
    Code:
    CREATE PROC [dbo].[rsp_SessionState_Save]
    (
    	@UserId uniqueidentifier
    	, @Name varchar(128) 
    	, @Value varchar(8000)
    )
    AS
    BEGIN
    	IF NOT EXISTS(SELECT 1 FROM dbo.SessionState WHERE UserId = @UserId AND Name = @Name)
    		INSERT INTO dbo.SessionState (UserId, Name, Value) VALUES(@UserId, @Name, @Value)
    	ELSE
    		UPDATE dbo.SessionState SET Value = @Value WHERE UserId = @UserId AND Name = @Name
    END
    Place the following code in your code-behind of your .aspx page. It requires references to System.Text, System.Data, System.SqlClient, System.Configuration. Don't forget to change your connection string.
    Code:
    public static DataTable readAll(string userId)
    {
        SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString);
    
        string tsql = "SELECT Name, Value FROM dbo.SessionState WHERE UserId = @UserId ORDER BY Name ASC";
    
        SqlCommand cmd = new SqlCommand(tsql, cn);
        cmd.Parameters.Add(new SqlParameter("@UserId", userId));
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        try {
        cn.Open();
        da.Fill(dt);
        } catch (Exception ex) {
             //do error processing
        }
        finally {
        cmd.Dispose();
        cn.Dispose();
        }
        return dt;
    }
    protected void httpStateInit(string userId)
    {
    
        StringBuilder s = new StringBuilder();
    
        s.Append("<script type=\"text/javascript\">\n");
        s.Append("Ext.state.Manager.setProvider(new Ext.ux.HttpProvider({url: 'http-state.ashx', user: 'XXX', session: 'session', id: '1', readBaseParams: { cmd: 'readState' }, saveBaseParams: { cmd: 'saveState' }, autoRead: false}));\n");
        s.Append("Ext.state.Manager.getProvider().initState([");
    
        DataTable dt = readAll(userId);
    
        int cnt = dt.Rows.Count;
        if (cnt > 0)
        {
            int x = 1;
            foreach (DataRow dr in dt.Rows)
            {
                s.Append(String.Format("[[\"name\":\"{0}\",\"value\":\"{1}\"]]\n", dr["Name"], dr["Value"]).Replace("[[", "{").Replace("]]", "}"));
                if (x < cnt)
                    s.Append(",");
                x++;
            }
        }
    
        s.Append("]);\n</script>");
        stateInit = s.ToString();
    
    }
    In the same page, you need three additional items, create a variable named stateInit, place some code in the page load function, and place a reference to stateInit in the .aspx.

    First, place the following code in your code behind (this should be a part of the page's class)

    Code:
    protected string stateInit = String.Empty;
    Next, place this code in the Page_Load function

    Code:
    string userId = Membership.GetUser(User.Identity.Name).ProviderUserKey.ToString();
    httpStateInit(userId);
    And now add the following code just below your js script references Saki's HttpState js.
    Code:
    <%=stateInit %>
    Next we'll create the generic handler that handles the save state requests.
    Create a new Generic Handler item and overwrite it with the following code, it must be named http-state.ashx (or anything else as long as you remember to change the reference in the code section above. Currently, i have only included the saveState as the readState i handle up front on page load. Don't forget to change your connection string.

    Code:
    <%@ WebHandler Language="C#" Class="http_state" %>
    
    using System;
    using System.Web;
    using System.Web.Security;
    
    public class http_state : IHttpHandler {
        
        public void ProcessRequest (HttpContext context) {
    
            HttpResponse Response = context.Response;
            HttpRequest Request = context.Request;
            Response.ContentType = "text/plain";
            Response.Expires = -100;
            
            string result = "{\"success\":false}";
            
            string uid = Membership.GetUser(context.User.Identity.Name).ProviderUserKey.ToString();
            string data = String.Empty;
            string cmd = String.Empty;
    
            if (Request.Form["cmd"] != null)
                cmd = Request.Form["cmd"].ToString();
            if (Request.Form["data"] != null)
                data = Request.Form["data"].ToString();
    
            switch (cmd) { 
                case "readState":
                    
                    break;
                case "saveState":
    // this assumes only a single element state is being passed
                    string[] s = data.Replace("[", "").Replace("]", "").Split(',');
                    if (s.Length == 2)
                    {
                        string name = s[0].Replace("{\"name\":","").Replace("\"", "");
                        string value = s[1].Replace("}","").Replace("\"value\":", "").Replace("\"", "");
                        save(uid, name, value);
                        result = "{\"success\":true}";
                    }
                    break;
                case "reset":
    // in case things get messed up, easily clear the user's state data (make sure they reload their page)
                    reset(uid);
                    break;
                    
            }
    
            Response.Write(result);
        }
     
        public bool reset(string userId)
        {
            bool ret = true;
            SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);
            SqlCommand cmd = new SqlCommand("DELETE FROM dbo.SessionState WHERE UserId = @UserId", cn);
            cmd.Parameters.Add(new SqlParameter("@UserId", userId));
    
            try
            {
                cn.Open();
                cmd.ExecuteNonQuery();
    
            }
            catch (Exception ex)
            {
                //Audit.Event(0, "DAL.SessionState.reset", ex.Message);
                ret = false;
    
            }
            finally
            {
                cmd.Dispose();
                cn.Dispose();
            }
    
            return ret;
    
        }
        public bool save(string userId, string name, string value)
        {
            bool ret = true;
            SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);
            SqlCommand cmd = new SqlCommand("dbo.rsp_SessionState_Save", cn);
            cmd.CommandType = CommandType.StoredProcedure;
    
            cmd.Parameters.Add(new SqlParameter("@UserId", userId));
            cmd.Parameters.Add(new SqlParameter("@Name", name));
            cmd.Parameters.Add(new SqlParameter("@Value", value));
    
            try
            {
                cn.Open();
                cmd.ExecuteNonQuery();
    
            }
            catch (Exception ex)
            {
                //Audit.Event(0, "DAL.SessionState.save", ex.Message);
                ret = false;
    
            }
            finally
            {
                cmd.Dispose();
                cn.Dispose();
            }
    
            return ret;
    
        }
    
    
        public bool IsReusable {
            get {
                return false;
            }
        }
    
    }
    Last edited by mystix; 1 Mar 2009 at 5:49 PM. Reason: moved to Examples from 2.x Ux and Plugins

  2. #2
    Ext JS Premium Member
    Join Date
    Jan 2009
    Location
    USA
    Posts
    127

    Default

    good work mate.

    my +1 for working example with the ability to save state of multiple elements and without membership.
    I will save me from tweaking my head for that.

  3. #3

    Thumbs up

    Can you provide me some additional meaning? I'm using asp.net, C#, and Extjs too and needs to add a login functionality. However, I do not want to have a page reload and do not know yet how to handle the state stuf (normaly I will use an asp.net cookie). Can you code be used in my context?

    Thanks for sharing bytheway!!!

  4. #4
    Ext JS Premium Member
    Join Date
    Sep 2008
    Posts
    38

    Default

    VATigers - i'll see what i can do. I'm a little overloaded at work right now, so may be a little while. Multiple elements... you could easily adjust the saveState code to split out additional elements. Our experience has shown it very rare for the httpstate to attempt multiple element save's in the same request. but that is only known to our own applications. For anon users, you might try enabling anon Profiles and grab the Providerkey from that.

    Gunmen - this code i meant to the store the state of extjs components (column widths/order, window position to name a couple). For your login, you'll need to create your own routines (not using the login control) and simply authenticate the user via the
    FormsAuthentication
    .Authenticate method and generate your own FormsAuthenticationTicket and cookie. Google these as there are plenty of examples of this out there. The one thing i'm not entirely sure about is whether or not an Ext.Ajax request would set the authentication cookie your request would return. We're about to try to find a solution for this as well.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •