【问题标题】:Using a Filter in SharePoint HTTPModule to intercept binary data returns corrupt data在 SharePoint HTTPModule 中使用筛选器拦截二进制数据会返回损坏的数据
【发布时间】:2011-02-04 14:03:29
【问题描述】:

我在 Stack Overflow 和 Google 上广泛研究了以下内容,但没有任何运气。在我解释我想要实现的目标和遇到的问题时,请耐心等待。

我正在开发一个 SharePoint 2007 应用程序,该应用程序向浏览器请求的任何图像(jpg、gif、png)添加基本水印。图像是否作为“12 hive”的一部分驻留在文档库或服务器的文件系统中并不重要。 (这是对正在构建的解决方案的简化,我不想用不相关的细节让你厌烦)。

由于这需要处理提供的任何图像,独立于可能在 SharePoint 上运行的第 3 方解决方案,我看到的唯一解决方案是编写一个 HTTPModule,挂钩模块的过滤器,从流并将其替换为图像的水印版本。无法为此使用 SharePoint 的事件接收器,并且 SharePoint 的“服务器端文件处理程序”并未涵盖将此类文件传送到浏览器的所有方案。

虽然使用过滤器拦截和修改基于文本的内容可以正常工作,但当过滤器包含二进制数据时,自定义过滤器的 Write 方法会收到损坏的数据。 byte[] 是正确的,直到在源文件中遇到 00,所以这听起来像是编码问题(二进制数据??)或 HTTPModule 过滤器不允许二进制数据,我很难相信。

奇怪的是,当 SharePoint 从服务器的文件系统中读取二进制文件(图像)时,它会正确地通过我的过滤器。但是,从 SharePoint 文档库中读取二进制文件时,数据已损坏。

为了确认这一点,我进行了以下测试:

  1. 从服务器的文件系统和 SharePoint 文档库请求 1.3MB TXT 文件可以正常工作。当从文件系统读取时,它会以一大块的形式到达。从文档库中读取时,它以 32KB 大小的块到达。

  2. 请求驻留在服务器文件系统上的 300KB 二进制映像由过滤器处理得很好。但是,从文档库中请求相同的文件会返回损坏的数据。

  3. 从文档库请求 3KB GIF 图像会返回损坏的数据。前 10 个字节正常,之后数据损坏(第 10 个字节在源文件中为 0)

  4. 当自定义过滤器未启用时,请求的文件总是成功返回到浏览器。

  5. 我们自定义过滤器的入口点是 Write 方法。传递给此方法的缓冲区中的数据已经损坏。

  6. 我了解多个 HTTPModule 是链接在一起的。我尝试将自定义模块放在 web.config 文件中模块列表的开头和结尾,但没有任何运气

HTTPModule中挂接过滤器的相关代码如下:

void context_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.Filter = new ResponseFilter(HttpContext.Current.Response.Filter);
}

ResponseFilter 类的实现如下。请注意,除了将源数据写回输出流之外,它实际上并没有做任何事情。

public class ResponseFilter : Stream
{
    private MemoryStream internalStream = new MemoryStream();
    private Stream responseStream;

    public ResponseFilter(Stream outputStream)
    {
        responseStream = outputStream;
    }

    public override void Flush()
    {
        responseStream.Flush();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        internalStream.Write(buffer, offset, count);
        responseStream.Write(buffer, offset, count);
    }

    public override void Close()
    {
        responseStream.Close();
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }

    public override long Length
    {
        get { return internalStream.Length; }
    }

    public override long Position
    {
       get { return internalStream.Position; }
       set { internalStream.Position = value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
       return internalStream.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin direction)
    {
       return internalStream.Seek(offset, direction);
    }

    public override void SetLength(long length)
    {
       internalStream.SetLength(length);
    }

}

这个类远非完美,但问题是在Write 方法被命中的那一刻,缓冲区中的数据已经损坏。课上的其他人暂时无所谓。

【问题讨论】:

    标签: asp.net sharepoint httpmodule


    【解决方案1】:

    这是一个老问题,您可能已经解决了这个问题。如果它仍然打开,您可能会考虑测试以查看关闭后缓存替换是否可以解决损坏问题。有关详细信息,请参阅ASP.Net Response Filter Clashing with SharePoint 2010 Publishing Site Defaults。这是一个很长的尝试,但也许值得花时间去测试。

    【讨论】:

      猜你喜欢
      • 2014-05-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多