|
■No87874 (abc さん) に返信
> もし何かヒントがありましたらコメント頂ければ幸いです。
紹介した記事のように HttpContext.Items を使うという話はどうなったのですか?
IIS のクラシックモードを使うのは諦めて統合パイプラインモードでやることにしたのですか?
そのあたりをクリアにしてもらえないと、この先私がお役に立てるかどうか分からないのですが・・・
とりあえず、検証に使った HTTP モジュールのコードをアップしておきます。環境は Windows 10
Pro 64-bit, ローカル IIS10, Visual Studio 2015 Cimmunity, .NET 4.6.1 です。
HTTP モジュールが動かないとか文字化けするという問題はありません。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
public class ResponseContentLogHttpModule : IHttpModule
{
public ResponseContentLogHttpModule()
{
}
public String ModuleName
{
get { return "ResponseContentLogHttpModule"; }
}
// In the Init function, register for HttpApplication
// events by adding your handlers.
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(this.Application_BeginRequest);
application.EndRequest += new EventHandler(this.Application_EndRequest);
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// Create HttpApplication and HttpContext objects to access
// request and response properties.
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
string filePath = context.Request.FilePath;
string fileExtension = VirtualPathUtility.GetExtension(filePath);
if (fileExtension.Equals(".aspx"))
{
HttpResponse response = context.Response;
var filter = new OutputFilterStream(response.Filter);
response.Filter = filter;
context.Items["OutputFilterStream"] = filter;
}
}
private void Application_EndRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
string filePath = context.Request.FilePath;
string fileExtension = VirtualPathUtility.GetExtension(filePath);
if (fileExtension.Equals(".aspx"))
{
var filter = (OutputFilterStream)context.Items["OutputFilterStream"];
string responseContent = filter.ReadStream();
WriteLog(responseContent);
}
}
private void WriteLog(string log)
{
string responseLogPath = HttpContext.Current.Server.MapPath("~/App_Data/log.txt");
using (var sw = new StreamWriter(responseLogPath, true))
{
sw.WriteLine(log);
}
}
public void Dispose() { }
}
public class OutputFilterStream : Stream
{
private readonly Stream InnerStream;
private readonly MemoryStream CopyStream;
public OutputFilterStream(Stream inner)
{
this.InnerStream = inner;
this.CopyStream = new MemoryStream();
}
public string ReadStream()
{
lock (this.InnerStream)
{
if (this.CopyStream.Length <= 0L ||
!this.CopyStream.CanRead ||
!this.CopyStream.CanSeek)
{
return String.Empty;
}
long pos = this.CopyStream.Position;
this.CopyStream.Position = 0L;
try
{
return new StreamReader(this.CopyStream).ReadToEnd();
}
finally
{
try
{
this.CopyStream.Position = pos;
}
catch { }
}
}
}
public override bool CanRead
{
get { return this.InnerStream.CanRead; }
}
public override bool CanSeek
{
get { return this.InnerStream.CanSeek; }
}
public override bool CanWrite
{
get { return this.InnerStream.CanWrite; }
}
public override void Flush()
{
this.InnerStream.Flush();
}
public override long Length
{
get { return this.InnerStream.Length; }
}
public override long Position
{
get { return this.InnerStream.Position; }
set { this.CopyStream.Position = this.InnerStream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.InnerStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
this.CopyStream.Seek(offset, origin);
return this.InnerStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
this.CopyStream.SetLength(value);
this.InnerStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
this.CopyStream.Write(buffer, offset, count);
this.InnerStream.Write(buffer, offset, count);
}
}
|