在windows中运行asp.net程序,如果直接SimpleWorkerRequest,那怕在aspx文件指定使用一种编码,也无法保证输出的页面不出现乱码。只有通过重载SimpleWorkerRequest....
重载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)
是我最感兴趣。分析Request.cs的源代码,我知道
SendResponseFromMemory(byte[] data, int length)
FlushResponse(bool finalFlush)
应是我需要重点考虑的
以下是MyRequest.cs的源代码
public class MyRequest:SimpleWorkerRequest
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
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)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
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);
}
![](/Images/OutliningIndicators/InBlock.gif)
private void initFilePath(string path)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
this._path = path;
string strVir = GetAppPathTranslated();
string str = strVir + path;
str = str.Replace("/","\\");
this._filePath = str;
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void SendResponseFromMemory(byte[] data, int length)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
if (length > 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
byte[] bytes = new byte[length];
Buffer.BlockCopy(data, 0, bytes, 0, length);
_responseBodyBytes.Add(bytes);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void FlushResponse(bool finalFlush)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
for (int i = 0; i < _responseBodyBytes.Count; i++)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
byte[] bytes = (byte[])_responseBodyBytes[i];
this.mem.Write(bytes,0,bytes.Length);
}
_responseBodyBytes = new ArrayList();
![](/Images/OutliningIndicators/InBlock.gif)
if (finalFlush)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
{
System.IO.StreamReader read = new StreamReader(this.mem);
this.mem.Position = 0;
string str = read.ReadToEnd();
this.writer.Write(str);
this.writer.Close();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
为什么使用MemoryStream来读取整个页面的字符串,再写到文件里呢?为什么为直接写到文件中呢?这是出于编码的考虑,直接写到文件中,文件内容的编码得不到保证,再使用IEWebbrowser打开的时候还是会出现乱码,尽管用记事本打开并没有看到乱码。如果使用IE打开,调整使用的编码你就能看到如windows程序一样的效果。
大家可能留意到代码保留了一个gb2312来构造StreamWriter的代码,使用gb2312的时候会有一个奇怪的现象,如果aspx页面编码指定是charset=gb2312的话,界面正常;如果是charset=utf-8时,IE自然会选择utf8,结果显示的页面乱码,只有选择为gb2312时才正常。使用utf8来构造StreamWriter就不存在这个问题。