jquery文件上传插件uploadify在.NET中session丢失的解决方案
基于jQuery和Flash的多文件上传插件uploadify的确很好用,具体配置和使用方法见以前的一篇文章:《一款基于jQuery的文件上传插件(.NET版)》。但今天在用这个插件的时候遇到了一个非常头痛的问题,上传文件的时候,我后台的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 %>" ; |
然后初始化插件的代码改成如下形式
$( "#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) { }, '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中比较麻烦),但这么好的一个文件上传插件,这样做很值得。希望能给遇到同样问题的朋友一点帮助。当然如果你有更好的解决方案,可以留言告诉我,不胜感激。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?