频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

Asp.NET大文件上传组件开发总结(二)

来源:天极网 作者:论坛整理 出处:巧巧读书 2008-07-10 进入讨论组

  为了实现Asp.NET大文件上传,我们需要首先需确定客户请求中发送的有文件内容,然后确定文件内容的位置。这部分对应的代码如下:


 1HttpApplication app = sender as HttpApplication;

2            HttpWorkerRequest request = GetWorkerRequest(app.Context);

3            

4            if (!IsUploadRequest(app.Request)) return; //不是文件上传,则退出

5            

6            string sContentType = app.Request.ContentType.ToLower();

7            byte[] arrBoundary = GetMultipartBoundary(sContentType);

8            int ContentLength = app.Request.ContentLength; //信息体的总长度

9

10            DataReader dataReader = new DataReader(app.Context.Request.ContentEncoding,arrBoundary);

11            DateTime startDate = DateTime.Now;

12            byte[] arrBuffer = request.GetPreloadedEntityBody();

13            if (arrBuffer == null)

14            {

15                arrBuffer = new Byte[0];

16                tempFile.Close();

17                return; //没有读取到信息体

18            }

19            else

20            {

21             这里是对文件内容的处理

22            } 

  上面的代码中,我们先获取Asp.NET对客户端请求的处理对象HttpWorkerRequest,然后根据这个对象的ContentType属性是否为multipart/form-data来确定对应的请求是否有上传文件,如果没有上传文件,就不处理此请求,以提高处理效率。这样处理的依据是,在有文件上传的HTML Form中,对应的enctype属性为multipart/form-data。这样就解决了确定客户端请求中是否发送有文件内容。

  要确定文件的内容位置,为此我们需要使用Reflector工具反编译System.Web.dll中HttpRequest的代码,可以发现有一个GetEntireRawContent方法,这个方法里,调用了HttpWorkerRequest对的GetPreloadedEntityBody方法来获取数据,可喜的是,这个方法是Public的,所以我们也可以直接调此方法来获取客户端发送的数据。

  获取数据后,我们可以将这些数据写入到一个文件中,这些数据是byte[]类型的,在写入文件时,因为Http协议是基于文本的,所以我们可以采用System.Text.Encoding.GetString方法,将这些字节数组编码成字符串,我这里的编码采用ASCII,只是这样请求中的中文就成了乱码。这样就可以获取请求的内容的文体格式,以方便我们分析(在代码中,这个写文件的功能我已去除,因为这里写全部请求内容只是用于分析使用,请参见第一篇文章中我列出的请求内容示例)。

  通过分析这些请求内容,我们可以发现:每个页面控件,均可以在这里找到对应的内容,两个控件内容间是用字符串“-----------------------------7d81e441d025c”分隔的。同时在我们反编译System.Web.dll中HttpRequest的代码时,也可以发有GetMultipartBoundary这个方法,这个方法我们可以从字面意思得知是取分隔标识。我们把这个方法提取出来:


1private byte[] GetMultipartBoundary()

2{

3    string attributeFromHeader = GetAttributeFromHeader(this.ContentType, "boundary");

4    if (attributeFromHeader == null)

5    {

6        return null;

7    }

8    attributeFromHeader = "--" + attributeFromHeader;

9    return Encoding.ASCII.GetBytes(attributeFromHeader.ToCharArray());

10} 

  然后我们采用这个方法,就可以从请求的内容中提取出类似“-----------------------------7d81e441d025c”这样的字符串。这样,我们就可以分隔页面内不同控件的内容了。

  最后,我们分析文件上传控件的内容:

Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings
\Administrator\??????\componentart.web.ui.rar"
Content-Type: application/x-rar-compressed
Rar! ??s
  我们可以发现,文件上传控件有一个filename属性,然后,下一行指定文件的MIME类型,随后这个空白行,在空白行下面,直到下一处类似“-----------------------------7d81e441d025c”标志字符串间,就是客户端发送的文件内容。我们只需把这些内容写入到服务器文件中即可。

  这里,文件内容的提取的问题就可以解决了。在提取文件内容时,对处理标志字符串时需要特别处理,防止标志字符分别读取到两个缓冲区中,所以这部分代码还是比较多的,具体请参看源代码中的DataReader类。

更多文章 更多内容请看.NET移动与嵌入式技术.NET开发手册ASP.NET教程专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章