我试图计算HTTP Response
的长度。
似乎流不想播放。 (不允许读取。并且内容长度似乎没有设置)
我希望简单地在HttpContent
响应中调用一些长度属性。
从那以后,我用谷歌搜索,看到了什么看起来像我不明白的过滤器周围的复杂解决方案。
是否可以访问长度(内容本身是额外的选项)
如果不是,我会很感激包含“mvc4 / .net 4.5过滤器”示例的链接
我应该工作,直到我理解。 :-)
public override void Init()
{
base.Init();
EndRequest += new EventHandler(EndRequestHandler);
}
public void EndRequestHandler(object sender, EventArgs e) {
var admService = new AdminServices();
admService.HTTPTrace(Context);
}
public void HTTPTrace(HttpContext httpContext) {
try {
var eventTrace = new MasterEventTrace();
eventTrace.RemoteAddress = req.UserHostAddress;
eventTrace.RequestLengthBytes = req.ContentLength;
// var targetMemoryStream = new MemoryStream();
// res.OutputStream.CopyTo(targetMemoryStream);
int len;
int.TryParse(res.Headers["Content-Length"], out len );
eventTrace.StatusCode = res.StatusCode;
eventTrace.ResponseLengthBytes = len; // <<<<<<< HOW to calculate this
编辑:基于Darin的回复,我得到了这个工作,谢谢Darin 我做了一些调整以适应这种情况,但另有建议。 它显示了Global.asax.cs中的更多信息,并根据需要记录了请求和响应信息。
//Global.asax.cs
public override void Init() {
base.Init();
BeginRequest += new EventHandler(BeginRequestHandler);
EndRequest += new EventHandler(EndRequestHandler);
}
public void EndRequestHandler(object sender, EventArgs e)
{
var adminService = new AdminServices();
var handler = Context.Response.Filter as ResponseStreamHandler;
adminService.HTTPTrace(Context, handler);
}
public void BeginRequestHandler(object sender, EventArgs e)
{
BootStrapUnauthentiated();
Context.Response.Filter = new ResponseStreamHandler(Context.Response.Filter);
}
public void HTTPTrace(HttpContext httpContext, ResponseStreamHandler responseStreamFilter)
{
try {
var _ILuwMaster = BosGlobal.BGA.ILuwMaster();
var req = httpContext.Request;
var res = httpContext.Response;
var eventTrace = new MasterEventTrace();
eventTrace.EventName = req.RequestType +":"+ req.Url.LocalPath;
eventTrace.EventDateTime = BosGlobal.BGA.Calendar.Now;
eventTrace.RemoteAddress = req.UserHostAddress;
eventTrace.RequestLengthBytes = req.ContentLength;
eventTrace.ResponseLengthBytes = responseStreamFilter.ResponseSize; //<<<<<<HERE
eventTrace.StatusCode = res.StatusCode;
// save trace entry in DB
_ILuwMaster.GetRepository<MasterEventTrace>().Add(eventTrace);
_ILuwMaster.Commit();
}
catch (Exception ex ) {} // DONT KILL Live traffic when logging errors occur
}
public class ResponseStreamHandler : MemoryStream {
private readonly Stream _responseStream;
public long ResponseSize { get; private set; }
public ResponseStreamHandler(Stream responseStream) {
this._responseStream = responseStream;
ResponseSize = 0;
}
public override void Write(byte[] buffer, int offset, int count) {
this.ResponseSize += count;
this._responseStream.Write(buffer, offset, count);
}
public override void Flush() {
base.Flush();
}
}
答案 0 :(得分:6)
你可以写一个custom Response filter:
public class ResponseLengthCalculatingStream: MemoryStream
{
private readonly Stream responseStream;
private long responseSize = 0;
public ResponseLengthCalculatingStream(Stream responseStream)
{
this.responseStream = responseStream;
}
public override void Write(byte[] buffer, int offset, int count)
{
this.responseSize += count;
this.responseStream.Write(buffer, offset, count);
}
public override void Flush()
{
var responseSize = this.responseSize;
// Here you know the size of the response ...
base.Flush();
}
}
并在Global.asax
:
protected void Application_BeginRequest()
{
Context.Response.Filter = new ResponseLengthCalculatingStream(Context.Response.Filter);
}
如果您只想对特定的控制器操作应用此过滤器,您可以编写自定义操作过滤器,而不是将其应用于Global.asax中的BeginRequest事件:
public class ResponseLengthCapturingAttribute: ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var response = filterContext.HttpContext.Response;
response.Filter = new ResponseLengthCalculatingStream(response.Filter);
}
}
然后剩下的就是使用相应的动作过滤器来装饰控制器动作:
[ResponseLengthCapturing]
public ActionResult Index()
{
...
return View();
}