C#ASP.NET MVC:显示页面渲染时间

时间:2009-09-15 18:08:43

标签: c# asp.net-mvc

我想通过母版页向我的所有ASP.NET MVC页面添加一个输出,该母版页显示当前页面的渲染时间。我怎么能这样做?

3 个答案:

答案 0 :(得分:10)

这很棘手,因为在您渲染页面之前,您必须将所有ViewData添加到其中。

您可以通过编写自定义ActionFilterAttribute并覆盖OnActionExecuting来启动计时器来获取执行控制器操作所需的总时间,并OnActionExecuted获取已用时间和存储它到ViewData。执行ActionResult时,可能需要花费时间并将其渲染到View中。

这可能足以满足您的需求?不幸的是,为了获得正在执行的Action和Result的总时间,您需要覆盖Controller中的OnActionExecutingOnResultExecuted,但此时将信息添加到控制器中为时已晚查看,因为它已经被渲染。你可以log it to a file however, see this link for an example


好的,这是一个示例计时器操作过滤器。将此类作为类添加到项目中,然后您可以使用[ActionTimer]标记任何控制器方法,并将经过的时间添加到名为“_ElapsedTime”的ViewData存储桶中,您可以将其打印出来你的意见。

using System.Web.Mvc; 
using System.Diagnostics;

namespace MvcApplication1  {
    public class ActionTimerAttribute : ActionFilterAttribute
        {
            public ActionTimerAttribute()
            {
                // Make sure this attribute executes after every other one!
                this.Order = int.MaxValue;
            }

            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                var controller = filterContext.Controller;
                if (controller != null)
                {
                    var timer = new Stopwatch();
                    controller.ViewData["_ActionTimer"] = timer;
                    timer.Start();
                }
                base.OnActionExecuting(filterContext);
            }

            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                var controller = filterContext.Controller;
                if (controller != null)
                {
                    var timer = (Stopwatch)controller.ViewData["_ActionTimer"];
                    if (timer != null)
                    {
                        timer.Stop();
                        controller.ViewData["_ElapsedTime"] = timer.ElapsedMilliseconds;
                    }
                }
            }
        } }

正如我之前提到的,这将不包括实际呈现ActionResult所花费的时间。如果您看一下我链接的示例,它会向您展示如何对日志文件执行此操作,并且还可以让您了解如何使用这四个操作过滤器事件。

答案 1 :(得分:0)

如果您想时间操作,您可以创建一个 IActionFilter ,它有启动和停止事件 OnActionExecuting OnActionExecuted 即可。但那只是控制器时间。

要获取全职,您还需要知道 IResultFilter 的开始和停止时间,其中包含 OnResultExecuting 的事件OnResultExecuted

This 示例,实际写入 OnResultExecuted 中的响应,因此它这表明当时仍有可能。它在OnResultExecuted方法中执行 filterContext.HttpContext.Response.Write 调用。

对于我个人而言,我只是想知道谁在做什么,哪些页面受到打击,以及表现明智,是什么花费了太多时间。我将其记录到数据库中,但不要将其放在每个页面上。 (我也会存储用户,如果经过身份验证,则不会显示如下。)

特别是,它适用于DevExpress大数据网格,这使我不仅需要对Action进行计时,还要开始对结果进行计时。

 public class Log : FilterAttribute, IActionFilter, IResultFilter
{
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        try
        {
            var db = new SomeExampleEntities();
            WebLog webLog = new WebLog();

            webLog.LogDate = DateTime.Now;

            // Whatever you want to log
            webLog.Path = filterContext.HttpContext.Request.Path;
            webLog.IPAddress = filterContext.HttpContext.Request.UserHostAddress;
            webLog.SessionId = filterContext.HttpContext.Session.SessionID;

            db.WebLogs.Add(webLog);
            db.SaveChanges();

            filterContext.HttpContext.Items["WebLog"] = webLog;
            filterContext.HttpContext.Items["WebLog_db"] = db;
        }
        catch
        {

        }
    }

    // This is fired when leaving the controller action, before running the View/Result
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
            WebLog webLog = (WebLog)filterContext.HttpContext.Items["WebLog"];
            webLog.ActionElapsed = (decimal)(((TimeSpan)(DateTime.Now - webLog.LogDate)).TotalMilliseconds / 1000.0000);
    }

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
        //Do Nothing
    }

    //This is fired after the result is actually executed, not just after the Action returns a View or Result
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        try
        {
            UsisWebEntities db = (UsisWebEntities)filterContext.HttpContext.Items["WebLog_db"];
            WebLog webLog = (WebLog)filterContext.HttpContext.Items["WebLog"];

            webLog.Elapsed = (decimal)(((TimeSpan)(DateTime.Now - webLog.LogDate)).TotalMilliseconds / 1000.0000);
            webLog.ResultElapsed = webLog.Elapsed - webLog.ActionElapsed;

            db.SaveChanges();
        }
        catch 
        {

        }
    }

}

答案 2 :(得分:-2)

我建议使用JavaScript。

在页面加载开始时有两次,在页面末尾有一次,然后你可以对总时间做一些改变。

通过从客户端脚本执行此操作,您可以获得加载页面的整个时间以及服务器所需的时间。