简单的方法来计算MVC4响应长度 [英] Simple way to calculate Response length in MVC4

查看:205
本文介绍了简单的方法来计算MVC4响应长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图来计算 HTTP响应的长度。
似乎流不想玩。 (没有读取允许的。和内容长度似乎不设置)
我希望能简单地呼吁 HttpContent 响应一些length属性。
因为我已经一派,看到的在我看来像周围的过滤器令人费解的解决方案,我不明白。
是否有可能访问的长度(内容本身是额外的选项)
如果不是我想AP preciate一个例子的链接mvc4 / .NET 4.5过滤器包括
我应该工作,但直到我明白。 :-)

 公共覆盖无效的init()
    {
        base.Init();
        EndRequest + =新的EventHandler(EndRequestHandler);
    }
    公共无效EndRequestHandler(对象发件人,EventArgs的发送){
        VAR admService =新AdminServices();
        admService.HTTPTrace(上下文);
    }
 公共无效HTTPTrace(HttpContext的HttpContext的){
        尝试{
            VAR eventTrace =新MasterEventTrace();
            eventTrace.RemoteAddress = req.UserHostAddress;
            eventTrace.RequestLengthBytes = req.Co​​ntentLength;          // VAR targetMemoryStream =新的MemoryStream();
          // res.OutputStream.CopyTo(targetMemoryStream);
            INT LEN;
            int.TryParse(res.Headers [内容长度],出LEN);
            eventTrace.Status code = res.Status code;
            eventTrace.ResponseLengthBytes = LEN; //<<<<<<<如何计算这个

编辑:根据达林的回应我得到这个工作,谢谢达林
我做了一些调整,以适应形势,但在其他方面的建议。
这表明从Global.asax.cs中多一点,并根据需要记录的请求和响应信息。

  //的Global.asax.cs
  公共覆盖无效的init(){
        base.Init();
        的BeginRequest + =新的EventHandler(BeginRequestHandler);
        EndRequest + =新的EventHandler(EndRequestHandler);
    }   公共无效EndRequestHandler(对象发件人,EventArgs的发送)
    {
        VAR adminService =新AdminServices();
        VAR处理器= Context.Response.Filter为ResponseStreamHandler;
        adminService.HTTPTrace(上下文,处理程序);
    }    公共无效BeginRequestHandler(对象发件人,EventArgs的发送)
    {
        BootStrapUnauthentiated();
        Context.Response.Filter =新ResponseStreamHandler(Context.Response.Filter);
    } 公共无效HTTPTrace(HttpContext的HttpContext的,ResponseStreamHandler responseStreamFilter)
    {
        尝试{
            变种_ILuwMaster = BosGlobal.BGA.ILuwMaster();            VAR REQ = httpContext.Request;
            VAR解析度= httpContext.Response;
            VAR eventTrace =新MasterEventTrace();
            eventTrace.EventName = req.RequestType +:+ req.Url.LocalPath;
            eventTrace.EventDateTime = BosGlobal.BGA.Calendar.Now;
            eventTrace.RemoteAddress = req.UserHostAddress;
            eventTrace.RequestLengthBytes = req.Co​​ntentLength;
            eventTrace.ResponseLengthBytes = responseStreamFilter.ResponseSize; //<<<<<<这里
            eventTrace.Status code = res.Status code;
            //保存在数据库跟踪条目
            _ILuwMaster.GetRepository< MasterEventTrace>()添加(eventTrace)。
            _ILuwMaster.Commit();
        }
        赶上(例外前){} //不杀害发生时记录错误实时路况
    } 公共类ResponseStreamHandler:MemoryStream的{
    私人只读流_responseStream;
    众长ResponseSize {搞定;私人集; }
    公共ResponseStreamHandler(流responseStream){
        this._responseStream = responseStream;
        ResponseSize = 0;
    }    公共覆盖无效写入(字节[]缓冲区,诠释抵消,诠释计数){
        this.ResponseSize + =计数;
        this._responseStream.Write(缓冲区,偏移数);
    }    公共覆盖无效的flush(){
      base.Flush();
    }
}


解决方案

您可以编写一个<一个href=\"http://www.west-wind.com/weblog/posts/2009/Nov/13/Capturing-and-Transforming-ASPNET-Output-with-ResponseFilter\">custom响应滤波器:

 公共类ResponseLengthCalculatingStream:MemoryStream的
{
    私人只读流responseStream;
    私人长期responseSize = 0;
    公共ResponseLengthCalculatingStream(流responseStream)
    {
        this.responseStream = responseStream;
    }    公共覆盖无效写入(字节[]缓冲区,诠释抵消,诠释计数)
    {
        this.responseSize + =计数;
        this.responseStream.Write(缓冲区,偏移数);
    }    公共覆盖无效的flush()
    {
        VAR responseSize = this.responseSize;
        //这里你知道响应的大小...
        base.Flush();
    }
}

和在它注册你的的Global.asax

 保护无效的Application_BeginRequest()
{
    Context.Response.Filter =新ResponseLengthCalculatingStream(Context.Response.Filter);
}

如果你想申请这个过滤器只在特定的控制器动作,你可以写一个自定义操作,而不是过滤器在Global.asax中应用它在BeginRequest事件的:

 公共类ResponseLengthCapturingAttribute:ActionFilterAttribute
{
    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        VAR响应= filterContext.HttpContext.Response;
        response.Filter =新ResponseLengthCalculatingStream(response.Filter);
    }
}

然后所有剩下的就是装饰用相应的动作过滤器控制器动作:

  [ResponseLengthCapturing]
公众的ActionResult指数()
{
    ...
    返回查看();
}

I was trying to calculate the length of a HTTP Response. Seems the stream doesn't want to play. (no read allowed. and the Content-Length doesn't seem set) I was hoping to simply call some length property on the HttpContent response. I have since googled and seen what looks to me like convoluted solutions around filters which I don't understand. Is it possible to access the length (content itself is option extra ) If not I would appreciate a link to an example for 'mvc4/.net 4.5 filter' included that I should work though till I do understand. :-)

   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

EDIT: Based on Darin's response I got this working, Thank You Darin I made a few tweaks to suit the situation, but otherwise as suggested. It shows a little more from Global.asax.cs, and logging the Request and Response info as required.

//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();
    }
}

解决方案

You could write a 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();
    }
}

and register it in your Global.asax:

protected void Application_BeginRequest()
{
    Context.Response.Filter = new ResponseLengthCalculatingStream(Context.Response.Filter);
}

And if you wanted to apply this filter only on particular controller actions you could write a custom action filter instead of applying it in the BeginRequest event in Global.asax:

public class ResponseLengthCapturingAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var response = filterContext.HttpContext.Response;
        response.Filter = new ResponseLengthCalculatingStream(response.Filter);
    }
}

and then all that's left is decorate the controller action with the corresponding action filter:

[ResponseLengthCapturing]
public ActionResult Index()
{
    ...
    return View();
}

这篇关于简单的方法来计算MVC4响应长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆