本帖最后由 robotbo 于 2012-02-28 12:03:09 编辑

解决方案 »

  1.   

           /// 结束请求后移除进度信息
            private void Application_EndRequest(Object sender, EventArgs e)
            {
                HttpApplication app = sender as HttpApplication;            if (IsUploadRequest(app.Request))
                {
                    SetUploadState(app, UploadState.Complete);
                    RemoveFrom(app);
                }        }
            /// 如果出错了设置进度信息中状态为“Error”
            private void Application_Error(Object sender, EventArgs e)
            {
                HttpApplication app = sender as HttpApplication;            if (IsUploadRequest(app.Request))
                {
                    SetUploadState(app, UploadState.Error);
                }        }        /// 设置当前上传进度信息的状态
            void SetUploadState(HttpApplication app, UploadState state)
            {
                string uploadId = app.Context.Request.Cookies["UploadID"].Value.ToString();
                if (uploadId != null && uploadId.Length > 0)
                {
                    Progress progress = GetProgress(uploadId, app.Application);
                    if (progress != null)
                    {
                        progress.SetState(state);
                        SetProgress(uploadId, progress, app.Application);
                    }
                }
            }        /// 设置当前上传的进度信息
            /// 根据UploadID记录在Application中
            void SetProgress(string uploadId, Progress progress, HttpApplicationState application)
            {
                if (uploadId == null || uploadId == string.Empty || progress == null)
                    return;
                application.Lock();
                application["Upload_" + uploadId] = progress;
                application.UnLock();
            }        /// <summary>
            /// 从Application中移出进度信息
            /// </summary>
            /// <param name="app"></param>
            void RemoveFrom(HttpApplication app)
            {
                string uploadId = app.Context.Request.Cookies["UploadID"].Value.ToString();
                HttpApplicationState application = app.Application;
                if (uploadId != null && uploadId.Length > 0)
                {
                    application.Remove("Upload_" + uploadId);
                    app.Context.Request.Cookies.Remove("UploadID");
                }
            }        /// <summary>
            /// 根据UploadID获取上传进度信息
            /// </summary>
            /// <param name="uploadId"></param>
            /// <param name="application"></param>
            /// <returns></returns>
            public static Progress GetProgress(string uploadId, HttpApplicationState application)
            {
                Progress progress = application["Upload_" + uploadId] as Progress;
                return progress;
            }        public HttpWorkerRequest GetWorkerRequest(HttpContext context)
            {            IServiceProvider provider = (IServiceProvider)HttpContext.Current;
                return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
            }        /// <summary> 
            /// 传入已上传完的数据 
            /// </summary> 
            /// <param name="request"></param> 
            /// <param name="textParts"></param> 
            public void InjectTextParts(HttpApplication app, byte[] textParts)
            {
                System.Reflection.BindingFlags bindingFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
                HttpWorkerRequest request = GetWorkerRequest(app.Context);
                Type type = request.GetType();            while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
                {
                    type = type.BaseType;
                }            if (type != null)
                {
                    type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
                    type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
                    type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);
                    type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
                }
            }        static bool StringStartsWithAnotherIgnoreCase(string s1, string s2)
            {
                return (string.Compare(s1, 0, s2, 0, s2.Length, true, System.Globalization.CultureInfo.InvariantCulture) == 0);
            }        /// <summary> 
            /// 是否为附件上传 
            /// 判断的根据是ContentType中有无multipart/form-data 
            /// </summary> 
            /// <param name="request"></param> 
            /// <returns></returns> 
            public bool IsUploadRequest(HttpRequest request)
            {
                return StringStartsWithAnotherIgnoreCase(request.ContentType, "multipart/form-data");
            } 
        }
    }
    [/code]
    文件上传用的用户控件,通过控件中iframe实现无刷新上传,上传页面是另外一个。但是在使用的时候发现一个问题,进度条有时不显示(js脚本请求数据后没有立即返回数据),恰恰在进度条不正常的时候文件可以上传成功,进度条正常的时候文件上传不成功
    后来发现是在InjectTextParts函数中,request得不到System.Web.Hosting.ISAPIWorkerRequest,没做处理就结束了,导致页面一直等待。我在想,会不会是在上传时,使用asp.net的回调函数(跟ajax一样的)同时请求了另外一个页面,导致在传入已上传完数据的时候request发生了变化,或者原来上传页面的request对象被获取进度页面的request代替了。不知道该怎么改,希望大家给点建议
      

  2.   

    呵呵- - 真实进度还是flash+Jquary给力呀...............>>>Uploadify.你这种做法目前已经不好用了- -浏览器兼容你得考虑吧。==
      

  3.   


      /// <summary>  
      /// 传入已上传完的数据  
      /// </summary>  
      /// <param name="request"></param>  
      /// <param name="textParts"></param>  
      public void InjectTextParts(HttpApplication app, byte[] textParts)
      {
      System.Reflection.BindingFlags bindingFlags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic;
      HttpWorkerRequest request = GetWorkerRequest(app.Context);
      Type type = request.GetType();  while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
      {
      type = type.BaseType;
      }  if (type != null)
      {
      type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
      type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
      type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);
      type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
      }
      }现在是这段代码有问题了,经过循环后type一直都是空,所以没法传入数据到管道。在这个页面获取数据后无法继续转到页面处理(页面有一个request.files[0])