HTTP响应滤波器不能解码响应字节的第二时间(HTTP Response filter can

2019-10-16 19:11发布

我开发了一个IIS 7的HttpModule。 我的目标是要检查特定标签的响应内容。 如果标签被找到,那么得到的东西记录。

为了实现我的目标我开发了一个自定义的ASP NET响应滤波器。 该过滤器扩展了.NET Stream类。

该过滤器获得注册的OnPreRequestHandlerExecute(对象源,EventArgs的)事件。

HTTP模块已正确注册。 该过滤器的工作。 问题是,当我刷新页面的撇了撇(字节[]缓冲区,诠释抵消,诠释计数)方法被调用如预期,但是,其解码是官样文章当字节的内容。

它让我困惑的是,为什么在第一时间响应字节得到正确解码,但是之后第二次请求(即页面刷新),他们都没有。 下面是编码其中过滤器被设置为与过滤器的写入方法的代码。 因为我已经花了3天,调试,研究谷歌和仍然没有喜悦任何帮助,将不胜感激。

public void OnPreRequestHandlerExecute(Object source, EventArgs e)
{

    HttpResponse response = HttpContext.Current.Response;
    if (response.ContentType == "text/html")
    {
        response.ContentEncoding = Encoding.UTF8; //forcing encoding UTF8
        response.Charset = "charset=utf-8";
        Encoding encoding = response.ContentEncoding;
        string encodingName = encoding.EncodingName;
        response.Filter = new MyFilter(response.Filter, response.ContentEncoding);
    }
}

    public override void Write(byte[] buffer, int offset, int count)
    {
        string strBuffer = string.Empty;

        try
        {
            strBuffer = Encoding.UTF8.GetString(buffer);
        }
        catch (EncoderFallbackException ex)
        {
            log(ex.Message);
        }


        // buffer doesn't contain the HTML end tag so we keep storing the 
        //incoming chunck of data

        if (!strBuffer.Contains("</html>"))
        {
            log(strBuffer.ToString() );
            _responseHtml.Append(strBuffer);

        }
        //the strbuffer contains the HTLM end tag ; we wrap it up now
  else
        {
            _responseHtml.Append(strBuffer); //append last chunck of data
            string finalHtml = _responseHtml.ToString();


               byte[] bytesBuffer = Encoding.UTF8.GetBytes(finalHtml);
                outputStream.Write(bytesBuffer, 0, bytesBuffer.Length);
            }

        }

    }

这是我得到的响应字节解码之后,第2次的HTML页面被调用(即在浏览器中刷新)

?\ B \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 YW ?? / ????噩?? V. \ AK T:?JHY ?? XP,U I Y???? ?\“\ 0 ??? W |????{?] ?? _}!?w ^ ??? \ 0R M Y ?? I7E ???Ž?? 8K ?? 50 8 ???? -6 K -1 ^〜ķ\?ú???? F·LE ????? S = I 10 GQY%22 O ???? <9X ??? BKuZg?一个??? 4? FQ ??? KJ?吨?? 8 ?????????? $é\?é?,?

UPDATE。

第一个定时器所以我不知道如何更新此。 所以我把我所做的缩小/解决问题。

首先,仍然没有喜悦。 :-(

这是我做的:

  1. 由于Write方法可以通过ASP NET调用不止一次,我字节存储在一个集合,将它们添加到集合,每一个Write方法得到由ASP NET调用时

p

ublic override void Write(byte[] buffer, int offset, int count)
                {

                        for (int i = 0; i < count; i++)
                        {
                            bytesList.Add(buffer[i]);
                        }
                        log("Write was called "+ "number of bytes: "+ bytesList.Count + " - " + count);
                }
  1. 在冲洗方法我调用,它收集到的所有字节的一些工作方法:

    公共覆盖无效冲洗(){字节[] bytesContent = ProcessResponseContent(bytesList); outputStream.Write(bytesContent,0,bytesContent.Length); outputStream.Flush(); }

    公共覆盖无效写入(字节[]缓冲器,诠释抵消,诠释计数){

      for (int i = 0; i < count; i++) { bytesList.Add(buffer[i]); } log("Write was called " + "number of bytes: " + bytesList.Count + " -" + count); } 

    专用字节[] ProcessResponseContent(列表bytesList){

      byte[] bytesArray = bytesList.ToArray(); string html = string.Empty; byte[] encodedBytes = null; try { FilterEncoder encoder = new FilterEncoder(); html = encoder.DecodeBytes(bytesArray.Length, bytesArray); encodedBytes = encoder.EncodeString(html); log("after encoding - encodedBytes" + encodedBytes.Length); log("after encoding - bytesArray" + bytesArray.Length); } catch (Exception ex) { log("exception ocurred " + ex.Message); 

    .... .....
    }

所述ProcessResponseContent是一个哑方法。 它只是转换字节到字节阵列的清单; 这个阵列的字节被解码为字符串。 现在,我们不应该有任何问题,因为我们得到了所有的字节,在响应中发送,在bytesList(名单)

字节数组被返回原封不动作为代码的目的是登录到一个文件中的解码的字符串。

        log("after decoding  " + html);

作为我创建了一个UTF8Encoding我捕获异常。 除了得到记录到文件中。

html页面被检索到的内容第一次获得登录到该文件。

当我刷新网页(Ctrl + F5)异常会记录:

“异常内容时发生无法从指定的代码页字节[图8B]在索引0处翻译为Unicode”

请承担记住,我的HTML页面的内容非常少。 所有的响应内容获取上一个块处理。

该页面被访问接收的字节数第一次是2805,这些字节解码成字符串权之前。

该页面被调出第二次(按Ctrl + F5)接收到多少字节,他们甚至解码之前,都是1436。

为什么反应少的字节数,我不知道。 这是影响解码操作,大概。

我希望这一切是有意义的,请让我知道,如果事情是不明确的。 我一直在寻找这个代码很长一段时间。

谢谢,

Answer 1:

这很难说这是否是所有的问题,但你忽略了offsetcount在参数Write ,而不是假定整个缓冲区是有效的:

strBuffer = Encoding.UTF8.GetString(buffer);

你还假定这将是一个完整的字符集 - 它可能含有(说)只是两个字节出三个字节字符。 你需要让你流状态,用一个Encoder从创建Encoding.UTF8保持通话之间部分写入字符的状态。

另外请注意,你认为自己会得到整体的</html>在一个呼叫-而你可以得到</在一个呼叫,以及html>在未来。 这有可能是真的 ASP.NET只叫你一次,在最后,但你可能不应该承担这样的话。



文章来源: HTTP Response filter can't decode the response bytes the second time