我一直在尝试将服务器端的XSLT转换作为IIS HttpModule实现。我的基本方法是在BeginRequest处安装一个新的过滤器,将写入重定向到MemoryStream中,然后在PreSendRequestContent处使用XSLT转换文档并将其写入原始输出流。然而,即使不执行转换,我显然也做错了什么,因为HttpModule似乎只能在第一次页面加载时工作,然后我就无法从服务器获得任何响应,直到重新启动应用程序池。如果进行转换,第一次会得到一个空白页面,然后没有响应。我显然做了些愚蠢的事情,但这是我多年来编写的第一段C#代码(也是我第一次尝试编写HttpModule),我不知道问题可能是什么。我犯了什么错误?(在下面的代码中,我已经注释掉了XSLT部分,并取消注释了一个将缓存内容写入响应的行。)
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Xsl;
namespace Onyx {
public class OnyxModule : IHttpModule {
public String ModuleName {
get { return "OnyxModule"; }
}
public void Dispose() {
}
public void Init(HttpApplication application) {
application.BeginRequest += (sender, e) => {
HttpResponse response = HttpContext.Current.Response;
response.Filter = new CacheFilter(response.Filter);
response.Buffer = true;
};
application.PreSendRequestContent += (sender, e) => {
HttpResponse response = HttpContext.Current.Response;
CacheFilter cache = (CacheFilter)response.Filter;
response.Filter = cache.originalStream;
response.Clear();
/* XmlReader xml = XmlReader.Create(new StreamReader(cache), new XmlReaderSettings() {
ProhibitDtd = false,
ConformanceLevel = ConformanceLevel.Auto
});
XmlWriter html = XmlWriter.Create(response.OutputStream, new XmlWriterSettings() {
ConformanceLevel = ConformanceLevel.Auto
});
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("http://localhost/transformations/test_college.xsl", new XsltSettings() {
EnableDocumentFunction = true
}, new XmlUrlResolver());
xslt.Transform(xml, html); */
response.Write(cache.ToString());
response.Flush();
};
}
}
public class CacheFilter : MemoryStream {
public Stream originalStream;
private MemoryStream cacheStream;
public CacheFilter(Stream stream) {
originalStream = stream;
cacheStream = new MemoryStream();
}
public override int Read(byte[] buffer, int offset, int count) {
return cacheStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count) {
cacheStream.Write(buffer, offset, count);
}
public override bool CanRead {
get { return cacheStream.CanRead; }
}
public override string ToString() {
return Encoding.UTF8.GetString(cacheStream.ToArray());
}
}
}