In this post, I’m going to explain in seven easy steps how to install MiniProfiler on an empty ASP.NET MVC web application.
Today, I wanted to add MiniProfiler to an ASP.NET MVC web application (not .NET Core), but unfortunately, the NuGet package doesn’t set up things correctly. The documentation is a bit lacking, and their sample project doesn’t work. So what was supposedly a simple task, took almost a full day of research to finally complete.
To keep things easy, let’s start with creating a new ASP.NET MVC application.
Choose ASP.NET web application project
Choose the MVC template
The correct NuGet package to install is MiniProfiler.MVC5
, which supplies the core MiniProfiler
package and provides the correct integration with ASP.NET MVC.
Install-Package MiniProfiler.Mvc5
The configuration happens in the Application_Start
, Application_BeginRequest
and Application_EndRequest
inside the Global.asax.cs
file.
Inside the Application_Start
you have to add the following line, to set up the default options.
MiniProfiler.Configure(new MiniProfilerOptions());
Moreover, then add the Application<em>BeginRequest and Application</em>EndRequest
methods to start and stop the tracking at each request.
protected void Application_BeginRequest()
{
MiniProfiler profiler = null;
if (Request.IsLocal)
{
profiler = MiniProfiler.StartNew();
}
}
protected void Application_EndRequest()
{
MiniProfiler.Current?.Stop();
}
You now need to include the scripts in the views. The easiest way is to add them in Shared/_Layout.cshtml
master view.
At the top, add the namespace using
declaration @using StackExchange.Profiling;
, and at the bottom, just before the </body>
@MiniProfiler.Current.RenderIncludes()
</body>
If you run the site now, nothing happens. This happens because MiniProfiler relies on a JavaScript library rendered at the moment, and it is requested as .js
, so usually, it wouldn’t be executed as .NET request. So, you have to add the following line in the web.config
.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Now, when you run the website, you get the MiniProfiler UI in the top left corner of the site. By clicking this, you can get the execution timings of the page.
*Basic profiling information *
The current view is not very useful, as it shows nothing apart from the overall execution. In an ASP.NET MVC application, you can start tracking a bit more information on the execution time of each action by adding a new filter into the pipeline. Open the FilterConfig.cs
file (if you are following along with the basic template) and add this line to the RegisterGlobalFilters
method
filters.Add(new ProfilingActionFilter());
Now, rerun the same site, and you’ll also see the execution time of the controller.
Profiling action and controllers
There is no real step seven…but it’s cool to have seven steps.
Jokes aside, now that the basic configuration is working, you can head to the official documentation to see how to start profiling portions of your code in a way that matters, usually done via the Step
and CustomTiming
methods.
Here is some sample code you could add to your actions to experiment a bit.
public ActionResult Index()
{
var profiler = MiniProfiler.Current;
using (profiler.Step("Set page title"))
{
ViewBag.Title = "Home Page";
}
using (profiler.Step("Doing complex stuff"))
{
using (profiler.Step("Step A"))
{
// simulate fetching a url
using (profiler.CustomTiming("http", "GET http://google.com"))
{
Thread.Sleep(10);
}
}
using (profiler.Step("Step B"))
{
// simulate fetching a url
using (profiler.CustomTiming("http", "GET http://stackoverflow.com"))
{
Thread.Sleep(20);
}
using (profiler.CustomTiming("redis", "SET \"mykey\" 10"))
{
Thread.Sleep(5);
}
}
}
// now something that loops
for (int i = 0; i < 15; i++)
{
using (profiler.CustomTiming("redis", "SET \"mykey\" 10"))
{
Thread.Sleep(i);
}
}
return View();
}
This code generates the trace shown in the following picture:
You can notice some interesting information detected by MiniProfiler. It detected that the code is calling the same 15 times (the loop at the bottom of the action method) and how much of the time is spent in different categories of operations (in the example, http
and redis
).
An additional feature to add would be tracking SQL statements with the EF6 integration.
#asp-net #web-development