Asp.NET大文件上传组件开发总结(四)---封送数据给Asp.NET页面

文/bashan  出处/博客园

    这个功能主要是为了不影响Asp.NET的处理模型,将请求中除上传的文件内容外的其它正常请求内容继续发送到Asp.NET页面处理。
    我们通过分析HttpRequest对象的GetEntireRawContent()方法在读取数据,并且发现这个方法在读取数据时,是将数据赋值到了_rawContent属性,所以我们只要能把处理后的数据赋值给HttpRequest对象的_rawContent属性,即可封送数据给Asp.NET页面。同时,由于我们改写了请求内容,所以HttpRequest的_contentLength也应当改写。

    由于这些属性方式是私有的,我们不能直接访问,所以我们必须采用反射的方法给属性赋值。代码如下:


private void InjectTextParts(HttpRequest request, byte[] textParts)
        {
            BindingFlags flags1 = BindingFlags.NonPublic | BindingFlags.Instance;
            Type type1 = request.GetType();
            FieldInfo info1 = type1.GetField("_rawContent", flags1);
            FieldInfo info2 = type1.GetField("_contentLength", flags1);
           
            if ((info1 != null) && (info2 != null))
            {
                Assembly web = Assembly.GetAssembly(typeof(HttpRequest));
                Type hraw = web.GetType("System.Web.HttpRawUploadedContent");
                object[] argList = new object[2];
                argList[0] = textParts.Length + 1024;
                argList[1] = textParts.Length;

                CultureInfo currCulture = CultureInfo.CurrentCulture;
                object httpRawUploadedContent = Activator.CreateInstance(hraw,
                                                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                                                        null,
                                                                        argList,
                                                                        currCulture,
                                                                        null);

              Type contentType = httpRawUploadedContent.GetType();

              FieldInfo dataField = contentType.GetField("_data", flags1);
              dataField.SetValue(httpRawUploadedContent, textParts);

              FieldInfo lengthField = contentType.GetField("_length", flags1);
              lengthField.SetValue(httpRawUploadedContent, textParts.Length);

              FieldInfo fileThresholdField = contentType.GetField("_fileThreshold", flags1);
              fileThresholdField.SetValue(httpRawUploadedContent, textParts.Length + 1024);

              info1.SetValue(request, httpRawUploadedContent);
              info2.SetValue(request, textParts.Length);
            }
        }


    在这里,在将代码用到NET2.0时,遇到了问题。因为在NET1.1时,HttpRequest的_rawContent属性是一个byte[]类型,但到了NET2.0,这个属性变成了HttpRawUploadedContent类型的对象,出现了赋值失败。通过查看HttpRawUploadedContent反射代码,发现原来这个类是为了将过大的请求内容写到磁盘文件中。没办法,我只有创建这个类的实例后再赋值给HttpRequest的_rawContent属性。这下能上传文件了,可是,Asp.NET页面的控件值全部丢失了,数据没有有效的封送到页面。嘿嘿,这里正好发挥我刚学会的一项技术---调试框架源码。于是从GetEntireRawContent()方法一路跟踪下去,发现是由于HttpRawUploadedContent对象的_length属性为零,导致HttpRequest对象认为没有有效数据而没有分析数据。导致通过HttpRequest的Params属性和Forms数据不能访问到请求内容。给这两个数据赋值后,哈!哈!一切顺利。上传过程全部结束!
由于NET2.0代码只是初步完成,等我在作进一步测试后,将在写完这部分总结后,提供给大家下载。

友情提示:此文并不表示本站肯定持有相同观点,转载请注明出处。
 您可能对 [Asp.Net] 的这些文章也感兴趣:

Creating a Custom Pager for GridView  ASPX页Web服务调用性能优化
合Jst和Css实现了在Asp.net下XP风格的下拉菜单  ASP.NET中的状态管理
如何设置tabcontrol控件的tabPage的text内容显示成竖着的字体  ASP.NET2.0 SQL Server2005构建多层应用
ASP.NET 2.0中TextBox服务器控件的ReadOnly和Disabled属性  C#中数据库操作
让Calendar在页面调用时才显示  用Asp.net实现基于XML的留言簿之三
C#重点知识详解(一)  CodeFile、Src、Codebehind三者的差别解释
Asp.NET大文件上传开发总结(一)  关于 IE 模态对话框的两个问题
ASP.NET设计网络硬盘之两重要类  在ASP.NET中实现多文件上传
在ASP.NET 中实现单点登录  OutOfMemoryException问题的处理
Duwamish7初探——数据流程  使用HttpWebRequest提交ASP.NET表单并保持Session和Cookie