Flash File Upload in Firefox with Session Management

Posted on 4/23/2008 | Printable Version | Comments (0)

To allow for multiple file uploads, we've found that the new Flash file upload component works very well. The flash (swf) gets placed on a page or control in your site, and allows you to select a list of files from your local machine to upload to the web server. When you click the Upload button, the flash component will post the files to a specified URL. In ASP.Net we create an ASHX (http handler) to handle the post, validate and save the files. Within the ASHX, we need to check the session to ensure that the current user is authenticated. To do this, your class must implement IRequiresSessionState:

public class Upload : IHttpHandler, System.Web.SessionState.IRequiresSessionState {  ...

Once you do this, sessions will be available. BUT!  Only in Internet Explorer! Turns out that Firefox, and probably many other browsers, don't carry over the cookie that stores the ASP.net session ID, and when you try to access the session from the handler, none of the values are there and context.Session.IsNewSession is true. After much searching, I was able to find a solution. 

The Solution
I should note that in our case we are using SqlServer session state, but I believe this applies to inProc as well. 

In your globa.asax.cs you can add the following:

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            /* Fix for the Flash Player Cookie bug in Non-IE browsers.
            * Since Flash Player always sends the IE cookies even in FireFox
            * we have to bypass the cookies by sending the values as part of the POST or GET
            * and overwrite the cookies with the passed in values.
            *
            * The theory is that at this point (BeginRequest) the cookies have not been read by
            * the Session and Authentication logic and if we update the cookies here we'll get our
            * Session and Authentication restored correctly
            */

            try
            {
                string session_param_name = "ASPSESSID";
                string session_cookie_name = "ASP.NET_SESSIONID";

                if (HttpContext.Current.Request.Form[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                }
            }
            catch (Exception)
            {
                Response.StatusCode = 500;
                Response.Write("Error Initializing Session");
            }

            try
            {
                string auth_param_name = "AUTHID";
                string auth_cookie_name = FormsAuthentication.FormsCookieName;

                if (HttpContext.Current.Request.Form[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                }

            }
            catch (Exception)
            {
                Response.StatusCode = 500;
                Response.Write("Error Initializing Forms Authentication");
            }
        }
        void UpdateCookie(string cookie_name, string cookie_value)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
            if (cookie == null)
            {
                cookie = new HttpCookie(cookie_name);
                HttpContext.Current.Request.Cookies.Add(cookie);
            }
            cookie.Value = cookie_value;
            HttpContext.Current.Request.Cookies.Set(cookie);

        }

** found this code here: http://www.sitepoint.com/forums/showthread.php?t=541283

If you don't have a Global.asax in your application, you can add one to your project by selecting the 'Global Application Class' file template from the Add >> New Item menu.

The next step is to pass in the session ID on the querystring from the flash movie. We have a generic swf that we use throughout the Waypoint system which accepts the target URL for the upload as a parameter in the FlashVars. When you render your flash movie from an asp.net page or user control, you can do the following:

<param name="FlashVars" value='uploadPage=Upload.ashx%3fASPSESSID=<%=Page.Session.SessionID%>'/>

This will pass in the session ID as part of the querystring for the upload page. Then you can make your flash movie use the uploadPage parameter to target the upload. The session ID will be read in on the request and the session variables will be loaded.

 


Comments

Be the first to comment below.

Post Comment