我想通过母版页向我的所有ASP.NET MVC页面添加一个输出,该母版页显示当前页面的渲染时间。我怎么能这样做?
答案 0 :(得分:10)
这很棘手,因为在您渲染页面之前,您必须将所有ViewData添加到其中。
您可以通过编写自定义ActionFilterAttribute
并覆盖OnActionExecuting
来启动计时器来获取执行控制器操作所需的总时间,并OnActionExecuted
获取已用时间和存储它到ViewData
。执行ActionResult时,可能需要花费时间并将其渲染到View中。
这可能足以满足您的需求?不幸的是,为了获得正在执行的Action和Result的总时间,您需要覆盖Controller中的OnActionExecuting
和OnResultExecuted
,但此时将信息添加到控制器中为时已晚查看,因为它已经被渲染。你可以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。
在页面加载开始时有两次,在页面末尾有一次,然后你可以对总时间做一些改变。
通过从客户端脚本执行此操作,您可以获得加载页面的整个时间以及服务器所需的时间。