为了提供文件内容我们需要首先需确定客户请求中发送的有文件内容然后确定文件内容的位置这部分对应的代码如下
HttpApplication app = sender as HttpApplication;
HttpWorkerRequest request = GetWorkerRequest(appContext);
if (!IsUploadRequest(appRequest)) return; //不是文件上传则退出
string sContentType = appRequestContentTypeToLower();
byte[] arrBoundary = GetMultipartBoundary(sContentType);
int ContentLength = appRequestContentLength; //信息体的总长度
DataReader dataReader = new DataReader(appContextRequestContentEncoding
arrBoundary);
DateTime startDate = DateTimeNow;
byte[] arrBuffer = requestGetPreloadedEntityBody();
if (arrBuffer == null)
{
arrBuffer = new Byte[];
tempFileClose();
return; //没有读取到信息体
}
else
{
这里是对文件内容的处理
}
上面的代码中我们先获取AspNET对客户端请求的处理对象HttpWorkerRequest然后根据这个对象的ContentType属性是否为multipart/formdata来确定对应的请求是否有上传文件如果没有上传文件就不处理此请求以提高处理效率这样处理的依据是在有文件上传的HTML Form中对应的enctype属性为multipart/formdata这样就解决了确定客户端请求中是否发送有文件内容
要确定文件的内容位置为此我们需要使用Reflector工具反编译SystemWebdll中HttpRequest的代码可以发现有一个GetEntireRawContent方法这个方法里调用了HttpWorkerRequest对的GetPreloadedEntityBody方法来获取数据可喜的是这个方法是Public的所以我们也可以直接调此方法来获取客户端发送的数据
获取数据后我们可以将这些数据写入到一个文件中这些数据是byte[]类型的在写入文件时因为Http协议是基于文本的所以我们可以采用SystemTextEncodingGetString方法将这些字节数组编码成字符串我这里的编码采用ASCII只是这样请求中的中文就成了乱码这样就可以获取请求的内容的文体格式以方便我们分析(在代码中这个写文件的功能我已去除因为这里写全部请求内容只是用于分析使用请参见第一篇文章中我列出的请求内容示例)
通过分析这些请求内容我们可以发现每个页面控件均可以在这里找到对应的内容两个控件内容间是用字符串dedc分隔的同时在我们反编译SystemWebdll中HttpRequest的代码时也可以发有GetMultipartBoundary这个方法这个方法我们可以从字面意思得知是取分隔标识我们把这个方法提取出来
private byte[] GetMultipartBoundary()
{
string attributeFromHeader = GetAttributeFromHeader(thisContentType boundary);
if (attributeFromHeader == null)
{
return null;
}
attributeFromHeader = + attributeFromHeader;
return EncodingASCIIGetBytes(attributeFromHeaderToCharArray());
}
然后我们采用这个方法就可以从请求的内容中提取出类似dedc这样的字符串这样我们就可以分隔页面内不同控件的内容了
最后我们分析文件上传控件的内容
ContentDisposition:formdata;name=file;filename=C:\DocumentsandSettings
\Administrator\??????\componentartwebuirar
ContentType:application/xrarcompressed
Rar!??s
我们可以发现文件上传控件有一个filename属性然后下一行指定文件的MIME类型随后这个空白行在空白行下面直到下一处类似dedc标志字符串间就是客户端发送的文件内容我们只需把这些内容写入到服务器文件中即可
这里文件内容的提取的问题就可以解决了在提取文件内容时对处理标志字符串时需要特别处理防止标志字符分别读取到两个缓沖区中所以这部分代码还是比较多的具体请参看源代码中的DataReader类