IIS 7 HttpModule を開発しました。私の目標は、特定のタグの応答コンテンツを確認することです。タグが見つかった場合、何かがログに記録されます。
この目標を達成するために、カスタマイズした ASP NET 応答フィルターを開発しました。このフィルターは、.NET Stream クラスを拡張します。
フィルタは、OnPreRequestHandlerExecute(Object source, EventArgs e) イベントに登録されます。
HTTP モジュールが正しく登録されました。フィルターは機能しています。問題は、ページを更新すると、Write the Write(byte[] buffer, int offset, int count) メソッドが期待どおりに呼び出されることですが、バイトをデコードするときの内容はグチャグチャです。
最初に応答バイトが正しくデコードされたのに、2 回目の要求 (つまり、ページの更新) の後では正しくデコードされない理由がわかりません。以下は、フィルターが設定されているコードと、フィルターのライター メソッドのコードです。私はすでに3日間、デバッグ、Googleでの調査を行っていましたが、まだ喜びがありませんでした。
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);
}
}
}
これは、応答バイトをデコードした後、htmlページが2回目に呼び出されたとき(つまり、ブラウザで更新したとき)に得られるものです
?\b\0\0\0\0\0\0?yw??/????Og??V.\ak?t:JhY??xP,u?I?Y? \"?\0???w?|?W???\0R?M?Y??I7E{?]??_}???z??8K??!?5O?8???? ??k?^?~k\?u????f?lE?????s=i??gqY%??O????<9x???BKuZg?a???4? Fq???KJ?t??8??????????$e\?E?,?
更新します。
初めてのタイマーなので、これを更新する方法がわかりません。そのため、問題を絞り込む/修正するために行ったことを入れています。
まず第一に、やはりノー・ジョイ。:-(
これは私がしたことです:
- Write メソッドは ASP NET によって複数回呼び出される可能性があるため、ASP NET によって Write メソッドが呼び出されるたびに、バイトをコレクションに格納してコレクションに追加します。
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);
}
フラッシュ メソッドでは、収集されたすべてのバイトに対して何らかの処理を行うメソッドを呼び出します。
public override void Flush() { byte[] bytesContent = ProcessResponseContent(bytesList); outputStream.Write(bytesContent, 0, bytesContent.Length); outputStream.Flush(); }
public 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); }
プライベートバイト[] ProcessResponseContent(List 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 (List ) に取得したため、問題は発生しません。
コードの目的はデコードされた文字列をファイルに記録することであるため、バイト配列はそのまま返されます。
log("after decoding " + html);
UTF8Encoding を作成したので、例外をキャッチしています。例外はファイルに記録されます。
HTML ページが初めて取得されたときに、コンテンツがファイルに記録されます。
ページを更新すると (Ctrl + F5)、例外がログに記録されます。
「例外が発生しました インデックス 0 のバイト [8B] を指定されたコード ページから Unicode に変換できません」
私の html ページのコンテンツは非常に小さいことに注意してください。すべての応答コンテンツが 1 つのチャンクで処理されます。
ページに初めてアクセスしたときの受信バイト数は 2805 です。これらのバイトが文字列にデコードされる直前。
ページが 2 回目に呼び出されたとき (Ctrl + F5)、受信されたバイト数は、デコードされる前でも 1436 です。
応答のバイト数が少ない理由はわかりません。これはデコード操作に影響を与えているのでしょうか。
これがすべて意味をなすことを願っています。不明な点があればお知らせください。私は長い間このコードを見てきました。
ありがとう、