问题描述
我一直在试图实现服务器端的XSLT转换为IIS HTTP模块。我的基本做法是安装在的BeginRequest一个新的过滤器转移写入到MemoryStream,然后在PreSendRequestContent使用XSLT转换文档,并将其写入到原来的输出流。然而,即使不进行改造,我清楚地做错事的出现的HttpModule为第一页负荷工作,然后我没有得到任何来自服务器的响应所有,直到我重新启动应用程序池。有了转变我得到一个空白页的第一次,然后没有任何反应。我清楚地做一些愚蠢的事,但是这是我写的年(和我在一个HttpModule首次尝试)的第一个C#代码,我不知道这个问题可能是什么。什么错误我在做? (我注释掉下面的代码的XSLT部分,注释掉高速缓存中的内容写入响应行。)
使用系统;
:使用System.IO;
使用System.Text;
使用的System.Web;
使用的System.Xml;
使用System.Xml.Xsl;
命名空间玛瑙{
公共类OnyxModule:IHttpModule的{
公共字符串模块名{
{返回OnyxModule }
}
公共无效的Dispose(){
}
公共无效初始化(HttpApplication的应用程序){
应用.BeginRequest + =(发件人,E)=> {
的HttpResponse响应= HttpContext.Current.Response;
response.Filter =新CacheFilter(response.Filter);
将Response.Buffer = TRUE;
};
application.PreSendRequestContent + =(发件人,E)=> {
的HttpResponse响应= HttpContext.Current.Response;
CacheFilter缓存=(CacheFilter)response.Filter;
response.Filter = cache.originalStream;
response.Clear();
/ *的XmlReader XML = XmlReader.Create(新的StreamReader(缓存),新的XmlReaderSettings(){
ProhibitDtd =假,
ConformanceLevel = ConformanceLevel.Auto
} );
的XmlWriter HTML = XmlWriter.Create(response.OutputStream,新XmlWriterSettings(){
ConformanceLevel = ConformanceLevel.Auto
});
XslCompiledTransform XSLT =新XslCompiledTransform();
xslt.Load(HTTP://localhost/transformations/test_college.xsl,新XsltSettings(){
EnableDocumentFunction =真
},新XmlUrlResolver());
xslt.Transform(XML,HTML); * /
的Response.Write(cache.ToString());
response.Flush();
};
}
}
公共类CacheFilter:MemoryStream的{
公共流originalStream;
私人的MemoryStream cacheStream;
公共CacheFilter(流流){
originalStream =流;
cacheStream =新的MemoryStream();
}
公共覆盖INT读(字节[]缓冲区,诠释抵消,诠释计数){
返回cacheStream.Read(缓冲区,偏移数);
}
公共覆盖无效写入(字节[]缓冲区,诠释抵消,诠释计数){
cacheStream.Write(缓冲区,偏移数);
}
公众覆盖布尔{的CanRead
{返回cacheStream.CanRead; }
}
公共重写字符串的ToString(){
返回Encoding.UTF8.GetString(cacheStream.ToArray());
}
}
}
当您完成读取数据到您的MemoryStream位置位于流的末尾。 。前的数据流发送到的StreamReader / XmlReader中,你需要重新设置位置为0
stream.Position = 0;
/ *或* /
stream.Seek(0,SeekOrigin.Begin);
I've been trying to implement server-side XSLT transformations as an IIS HttpModule. My basic approach is to install a new filter at BeginRequest that diverts writes into a MemoryStream, and then at PreSendRequestContent to transform the document using XSLT and write it to the original output stream. However, even without performing the transformation I'm clearly doing something wrong as the HttpModule appears to work for the first page load and then I get no response from the server at all until I restart the application pool. With the transformation in place I get an empty page the first time and then no response. I'm clearly doing something stupid but this is the first C# code I'd written in years (and my first attempt at an HttpModule) and I have no idea what the problem might be. What mistakes am I making? (I've commented out the XSLT part in the code below and uncommented a line that writes the contents of the cache to the response.)
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());
}
}
}
When you are done reading the data into your MemoryStream the position is at the end of the stream. Before sending the stream to the StreamReader/XmlReader you need to reset the position to 0.
stream.Position = 0;
/* or */
stream.Seek(0, SeekOrigin.Begin);
这篇关于我怎么能执行XSLT转换的一个HttpModule?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!