重载SimpleWorkerRequest
从MSDN上知道可以重载SimpleWorkerRequest来实现这现更多自己的行为。如何重载SimpleWorkerRequest?从Cassini的Request.cs源代码中,我们可以看到很多方法与实现方式,其中的
SendResponseFromMemory(
byte
[] data,
int
length)
SendResponseFromFile(String filename, long offset, long length)
SendResponseFromFile(IntPtr handle, long offset, long length)
SendResponseFromFileStream(FileStream f, long offset, long length)
FlushResponse( bool finalFlush)
SendResponseFromFile(String filename, long offset, long length)
SendResponseFromFile(IntPtr handle, long offset, long length)
SendResponseFromFileStream(FileStream f, long offset, long length)
FlushResponse( bool finalFlush)
是我最感兴趣。分析Request.cs的源代码,我知道
SendResponseFromMemory(byte[] data, int length)
FlushResponse(bool finalFlush)
应是我需要重点考虑的
以下是MyRequest.cs的源代码
public
class
MyRequest:SimpleWorkerRequest
{
private ArrayList _responseBodyBytes;
private System.IO.MemoryStream mem;
private System.IO.StreamWriter writer;
public MyRequest(string pWebPage, string pQuery,string pFile):base(pWebPage,pQuery,null)
{
this.mem = new MemoryStream();
// this.writer = new StreamWriter(pFile,false,Encoding.GetEncoding("gb2312"));
this.writer = new StreamWriter(pFile,false,Encoding.UTF8);
this._responseBodyBytes = new ArrayList();
this.initFilePath(pWebPage);
}
private void initFilePath(string path)
{
this._path = path;
string strVir = GetAppPathTranslated();
string str = strVir + path;
str = str.Replace("/","\\");
this._filePath = str;
}
public override void SendResponseFromMemory(byte[] data, int length)
{
if (length > 0)
{
byte[] bytes = new byte[length];
Buffer.BlockCopy(data, 0, bytes, 0, length);
_responseBodyBytes.Add(bytes);
}
}
public override void FlushResponse(bool finalFlush)
{
for (int i = 0; i < _responseBodyBytes.Count; i++)
{
byte[] bytes = (byte[])_responseBodyBytes[i];
this.mem.Write(bytes,0,bytes.Length);
}
_responseBodyBytes = new ArrayList();
if (finalFlush)
{
System.IO.StreamReader read = new StreamReader(this.mem);
this.mem.Position = 0;
string str = read.ReadToEnd();
this.writer.Write(str);
this.writer.Close();
}
}
{
private ArrayList _responseBodyBytes;
private System.IO.MemoryStream mem;
private System.IO.StreamWriter writer;
public MyRequest(string pWebPage, string pQuery,string pFile):base(pWebPage,pQuery,null)
{
this.mem = new MemoryStream();
// this.writer = new StreamWriter(pFile,false,Encoding.GetEncoding("gb2312"));
this.writer = new StreamWriter(pFile,false,Encoding.UTF8);
this._responseBodyBytes = new ArrayList();
this.initFilePath(pWebPage);
}
private void initFilePath(string path)
{
this._path = path;
string strVir = GetAppPathTranslated();
string str = strVir + path;
str = str.Replace("/","\\");
this._filePath = str;
}
public override void SendResponseFromMemory(byte[] data, int length)
{
if (length > 0)
{
byte[] bytes = new byte[length];
Buffer.BlockCopy(data, 0, bytes, 0, length);
_responseBodyBytes.Add(bytes);
}
}
public override void FlushResponse(bool finalFlush)
{
for (int i = 0; i < _responseBodyBytes.Count; i++)
{
byte[] bytes = (byte[])_responseBodyBytes[i];
this.mem.Write(bytes,0,bytes.Length);
}
_responseBodyBytes = new ArrayList();
if (finalFlush)
{
System.IO.StreamReader read = new StreamReader(this.mem);
this.mem.Position = 0;
string str = read.ReadToEnd();
this.writer.Write(str);
this.writer.Close();
}
}
为什么使用MemoryStream来读取整个页面的字符串,再写到文件里呢?为什么为直接写到文件中呢?这是出于编码的考虑,直接写到文件中,文件内容的编码得不到保证,再使用IEWebbrowser打开的时候还是会出现乱码,尽管用记事本打开并没有看到乱码。如果使用IE打开,调整使用的编码你就能看到如windows程序一样的效果。
大家可能留意到代码保留了一个gb2312来构造StreamWriter的代码,使用gb2312的时候会有一个奇怪的现象,如果aspx页面编码指定是charset=gb2312的话,界面正常;如果是charset=utf-8时,IE自然会选择utf8,结果显示的页面乱码,只有选择为gb2312时才正常。使用utf8来构造StreamWriter就不存在这个问题。