Flash Multiple-File-Upload mit FileReference und die gute Session

Ein kürzliches Problem kostete mich etliche Stunden. Ich habe einen Multiple-File Upload mit Flash und ASP.NET realisiert. Als Vorlage diente mir dieser Code: http://www.codeproject.com/KB/aspnet/FlashUpload.aspx

Funktioniert soweit ohne Probleme, ABER benutzt man diesen Code innerhalb eines geschützten Bereichs bzw. Session, gibt es ein Problem. Man erhält immer eine Session, wenn man auf den HttpHandler zugreift. Man könnte nun hergehen und z.B. die BenutzerID mittels GET-Parameter mit senden, ich habe jedoch den Weg gewählt die SessionID mit zusenden, damit ich nach wie vor auf alle Session-Parameter zugreifen kann.
Ich will nicht näher auf den Actionscript eingehen, alles was ihr dafür benötigt findet ihr hier: http://markshu.ca/imm/flash/tutorial/fileReference.html

Hinweis: Benutzt ihr den Script ohne Domain, könntet ich ein Sandbox Problem bekommen, einfach folgende Zeile im Actionscript hinzufügen: System.security.allowDomain(”deine IP”);

1) Flash einbinden:
Ich binde meine Flash-Filme immer mit AC_RunActiveContent ein, ihr findet in Google die einsprechenden Tutorials.

<script type="text/javascript"><!--
AC_FL_RunContent('FlashVars','uploadPage=photo_upload.ashx<%=GetFlashVars()%>&completeFunction=UploadComplete()', 'allowScriptAccess','always', 'codebase','http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0','width','600','height','300','src','fileUpload','quality','high','wmode','transparent','pluginspage','http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash','movie','fileUpload' ); //end AC code
 
// --></script>

Wie ihr seht übergebe ich die SessionID als Parameter uploadPage. Dieser wird benötigt um beim aufrufen des HttpHandlers die Session wieder zuzuweisen.

2) HttpHandler:
Der HttpHandler könnte wie folgt aussehen:


<%@ WebHandler Language="C#" Class="photo_upload" %>

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Web.SessionState;

public class photo_upload : IHttpHandler, IReadOnlySessionState
{
    public photo_upload()
    { 

    }  

    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return false; }
    }

    public void ProcessRequest(HttpContext context)
    {
        if(context.Session[”UserID”]==null)
        {
        	//user nicht eingeloggt
        	return;
        }

        if (context.Request.Files.Count > 0)
        {
            // loop through all the uploaded files
            for (int i = 0; i < context.Request.Files.Count; i++)
            {
                // get the current file
                HttpPostedFile uploadFile = context.Request.Files[i];
                // if there was a file uploded
                if (uploadFile.ContentLength > 0)
                {
                    //TODO: mache was mit dem FILE

                }
            }
        }
        // Mac bugfix damit onComplete event ausgelösst wird
        HttpContext.Current.Response.Write(” “);
        HttpContext.Current.Response.Flush();
    }

    #endregion
}

Hier nun das Problem, es wird eine neue Session (IsNewSession) angelegt und somit wäre „UserID“ null, obwohl sie zugewiesen ist.

3) global.asax Session zuweisen:
Folgender Code weißt die Session aufgrund der ID dem Benutzer zu.
Achtung: Ihr solltet die SessionID verschlüsseln, denn ansonsten könnte der Parameter in einem Netzwerk gesniffed werden und die Session übernommen werden.

protected void Application_BeginRequest(object sender, EventArgs e)
{
	HttpContext context = HttpContext.Current;
	if (context.Request["sid"] != null)
	{
	    HttpCookie sessioncookie = context.Request.Cookies.Get("ASP.NET_SESSIONID");

	    if(sessioncookie==null) //FF unter MAC problem
	        sessioncookie = new HttpCookie("ASP.NET_SESSIONID");

	    sessioncookie.Value = Bee17.Utils.DecodeSessionID(context.Request["sid"]);
	    context.Request.Cookies.Set(sessioncookie);
	}
}

Hinterlasse eine Antwort