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);
}
}
