基於jQuery和Flash的多文件上傳插件uploadify在asp.net下session丟失解決方案


示例Demo下載:

基於jQuery和Flash的多文件上傳插件uploadify的確很好用但今天在用這個插件的時候遇到了一個非常頭痛的問題,上傳文件的時候,我后台的session突然都丟失了,我進入調試去查看session變量發現為null悲劇,難道我不能用這個插件了嗎?當然不可能,這么好的東西當然要用起來,於是就去找解決方案了。 
終於,答案有了,原來一般情況下(非IE瀏覽器),因為諸如uploadify,swfupload采用的都是flash客戶端,這樣它們產生的useragent與用戶使用瀏覽器的 user-agent必然不同所以,雖然用戶登錄了你的系統產生了一個session,但是當觸發上傳程序時會產生另一個session(在上述 useragent選項開啟的情況下)所以,不是session丟失了,而是當你上傳文件時,CI為uploadify另外創建了一個session好了,既然找到問題的根源,我們就想辦法讓服務器在session判空之前將session值手動傳遞過去。

在ASP.NET中的解決方案如下:

    
在上傳的那個頁面中加入以下代碼
var auth = "<% = Request.Cookies[FormsAuthentication.FormsCookieName]==null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>"; 
var ASPSESSID = "<%= Session.SessionID %>"; 
然后初始化插件的代碼改成如下形式
view sourceprint?$("#fileInput1").uploadify({ 
'uploader': '/Scripts/uploader/uploadify.swf', 
'method': 'GET', 
'script': '/mystudio/GoUploadAvatar', 
'cancelImg': '/Scripts/uploader/cancel.png', 
'sizeLimit': 2048000, 
'multi': false, 
'fileDesc': '選擇jpg,png,gif', 
'fileExt': '*.jpg;*.png;*.gif', 
'onComplete': function (e, queueId, fileObj, response, data) { 
}, 
'scriptData': { 'ASPSESSID': ASPSESSID, 'AUTHID': auth },

'onSelectOnce': function (e, data) { $('#fileInput1').uploadifySettings('scriptData', { 'ASPSESSID': ASPSESSID, 'AUTHID': auth }); } }); 注意上面有一句,很關鍵 $('#fileInput1').uploadifySettings('scriptData', { 'ASPSESSID': ASPSESSID, 'AUTHID': auth });

接下來我們必須在服務端Session判空並創建之前,將傳遞過來的SessonID強制賦給當前請求的Cookies,這樣服務端就認為還是原來的Session傳遞過來了具體做法我們可以在Global.asax文件中加入如下代碼:

protected void Application_BeginRequest(object sender, EventArgs e)
    {
        /* we guess at this point session is not already retrieved by application so we recreate cookie with the session id... */
        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
        {

        }
        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
        {

        }
    }

    private void UpdateCookie(string cookie_name, string cookie_value)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);

        if (null == cookie)
        {
            cookie = new HttpCookie(cookie_name);
        }
        cookie.Value = cookie_value;
        HttpContext.Current.Request.Cookies.Set(cookie);
    } 

這時候你訪問上傳文件的那個頁面時可能會報“會話狀態已創建一個會話 ID,但由於響應已被應用程序刷新而無法保存它”的錯誤,這時,你可以在web.config文件改變session的存儲方式,一般默認都是以 “inproc”存儲的,我們把它改成stateserver模式,即在system.web節點下加入

<sessionstate mode="StateServer" stateconnectionstring="tcpip=127.0.0.1:42424" timeout="30"></sessionstate> 

OK,問題解決,雖然看起來解決這個問題比較麻煩(不知道在其他網站中怎么弄,至少在.NET中比較麻煩),但這么好的一個文件上傳插件,這樣做很值得希望能給遇到同樣問題的朋友一點幫助。當然如果你有更好的解決方案,可以留言告訴我,不勝感激。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM