MiniProfiler is an open source profiling library which monitors performance with the .Net application. It is very lightweight and fast. Using this, we can easily track the performance issue with our application. It is created by Stack Overflow Team member. 

To know more about MiniProfiler, just visit official site https://miniprofiler.com/

Why MiniProfileris useful?

Creating an application is not an easy task with the high-performance rate. But due to complex logic, mappings entities, using multiple libraries, good amount of HTML, CSS and JS code, Database logic, connectivity, and server response time etc. our application becomes too slow. And it becomes very hard to figure out the exact root causes which slow our application.

MiniProfiler is an awesome tool to figure out which portion of the application taking how much time in processing. We can easily see using MiniProfiler that how much time our database logic is taken, how much time is taken by our server response etc.  Basically, MiniProfiler helps us to know who is responsible to slow our application so that we can make an improvement on that part to make the application faster.

Setting up MiniProfiler with Asp.Net MVC Application

First create an application in Asp.Net MVC 4 and right-click on the project and choose “Manage NuGet Packages..” to install MiniProfiler for Asp.Net MVC application. As we can see with below screenshot that we have searched for MiniProfiler.MVC and going to install the second one “MiniProfiler.Mvc4”. We can also see the description of MiniProfiler that says “MiniProfiler which designed for Asp.Net MVC 4+ sites”. So, let install this to click on “Install” button from the right pane.

MiniProfiler Nuget

After MiniProfiler installation, we will find two references inside the Project Reference section as “MiniProfiler” and “MiniProfiler.Mvc”. Now its time to configure when MiniProfiler will start profiling to the application. So, make following entries inside the Global.asax file.

using StackExchange.Profiling;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace MiniProfilerTest
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
        protected void Application_BeginRequest()
        {
            if (Request.IsLocal)
            {
                //MiniProfiler will start at the begining of the request.
                MiniProfiler.Start();
            }
        }

        protected void Application_EndRequest()
        {
            //MiniProfiler will stop at the begining of the request.
            MiniProfiler.Stop();
        }
    }
}

 

As we have configured with above code that MiniProfiler should start profiling once new request gets the process and stop profiling at the end of the request.

Now, move to view and configure MiniProfiler, so that profiling data will get inside the HTML portion at the top left corner. To do that we have to add @MiniProfiler.RenderIncludes()” code with Layout page. We have chosen layout page because of we would like to profile each request which using this layout page.

@using StackExchange.Profiling

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")   
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)

    @MiniProfiler.RenderIncludes()
</body>
</html>

 

DO NOT DO

Don’t install “MiniProfiler” and then “MiniProfiler.Mvc4” or “MiniProfiler.Mvc3” one by one with Asp.Net MVC application. It will create an issue with MVC application and MiniProfiler will not work and you will get the following issue.

“localhost:port/mini-profiler-resources/results”  Not Found [404].

 

WHAT TO DO

  • Always install specific version when working with Asp.Net MVC application. For example, if working with Asp.Net MVC 4 then choose “MiniProfiler.Mvc4” from NuGet and install it or if working with Asp.Net MVC 3 then choose “MiniProfiler.Mvc3” from NuGet and install it.

  • If you get an error after running application with MiniProfiler.Mvc4 or MiniProfiler.Mvc3 which state “/mini-profiler-resources/includes.js 404 not found” then simply add the following line of code in Web.Config inside web server section.
<system.webServer>
    <handlers>
      <add name="MiniProfiler" path="mini-profiler-resources/*"
               verb="*" type="System.Web.Routing.UrlRoutingModule"
               resourceType="Unspecified" preCondition="integratedMode" />
    </handlers>   
</system.webServer>

 

Finally, we have done all installation and setting to configure MiniProfiler with Asp.Net MVC application, now we can run the application. To run, press F5 and application will be populated as following with MiniProfiler Data at the top left corner of the application. The output will be like as below image shown. Here we can see clearly that which event has taken how much time to process.

MiniProfiler with asp.net mvc

 

If we view “page source” than will find the following scripting code which is auto generated and added with the View to display the profiling data.

<script async type="text/javascript" id="mini-profiler" src="/mini-profiler-resources/includes.js?v=sudYtmATCtlvvgsiJ+ijDWT8sy88Fx31VI8aPQ/CYM8=" data-version="sudYtmATCtlvvgsiJ+ijDWT8sy88Fx31VI8aPQ/CYM8=" data-path="/mini-profiler-resources/" data-current-id="bd11c448-99dd-4c44-a49a-e248cc52bb83" data-ids="bd11c448-99dd-4c44-a49a-e248cc52bb83" data-position="left" data-trivial="false" data-children="false" data-max-traces="15" data-controls="false" data-authorized="true" data-toggle-shortcut="Alt+P" data-start-hidden="false" data-trivial-milliseconds="2"></script>

 

Now let move to see how MiniProfiler works with actual data. To complete this demonstration, we are going to create some dummy blog post data in one STEP and in next STEP, going to modify the actual username.

Note: I am creating dummy data inside the controller itself, instead of this we can get actual data from API.

We can define our own STEP to see which process taking how much time. So, basically, STEPs in MiniProfiler are used to see the performance of each process like getting data from the server, updating data on the server or posting data in Database etch.  Here I am going to create a list for Blog Post and define it inside one STEP. Another STEP will be defined to update the User Name for Blog Post as below code shown.

So, first let's create a model class for BlogPost which has few properties to define Blog data. So, create a class inside the Model folder as name “BlogPost”.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MiniProfilerTest.Models
{
    public class BlogPost
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Category { get; set; }
        public string Content { get; set; }
        public string UserName { get; set; }
    }
}

 

Now move to the home controller and define STEP, the first STEP will define for “Get Blog Post Data”. Here we are creating dummy details for Blog Post to show on View but instead of this, we can also get the actual data from our Services or APIs. With next STEP “Update User Info”, we are modifying the username based of the certain condition. Once model defines then it will be passed to View to render data on View in the tabular format.

using MiniProfilerTest.Models;
using StackExchange.Profiling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MiniProfilerTest.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var miniProfiler = MiniProfiler.Current;
            List<BlogPost> post = new List<BlogPost>();

            //Suppose getting blog post data form API call.
            using (miniProfiler.Step("Get Blog Post Data", ProfileLevel.Info))
            {
                post.Add(new BlogPost() { PostId = 1, Title = "Blog Post Title 1", Category = "Category 1", Content = "Content for Blog Post 1" });
                post.Add(new BlogPost() { PostId = 2, Title = "Blog Post Title 2", Category = "Category 2", Content = "Content for Blog Post 2" });
                post.Add(new BlogPost() { PostId = 3, Title = "Blog Post Title 3", Category = "Category 1", Content = "Content for Blog Post 3" });
                post.Add(new BlogPost() { PostId = 4, Title = "Blog Post Title 4", Category = "Category 2", Content = "Content for Blog Post 4" });
                post.Add(new BlogPost() { PostId = 5, Title = "Blog Post Title 5", Category = "Category 1", Content = "Content for Blog Post 5" });
            }

            using (miniProfiler.Step("Update User Info", ProfileLevel.Info))
            {
                //Suppose updating user name form API call update here.
                foreach (var item in post)
                {
                    if (item.PostId < 3)
                    {
                        item.UserName = "Mukesh Kumar";
                    }
                    else
                    {
                        item.UserName = "Admin";
                    }
                }
            }

            return View(post);
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }

}

 

It's time to render data on Index.cshtml view. So, make iteration on Model data and fill the table as follows.

@model IEnumerable<MiniProfilerTest.Models.BlogPost>

@{
    ViewBag.Title = "Home Page";
}

<div class="pull-right" style="width:600px;">
    <h3>MiniProfiler Test Data</h3>
    <table style="border:3px solid #808080;">
        <tr>
            <th>ID</th>
            <th>Title</th>
            <th>Category</th>
            <th>Content</th>
            <th>User</th>
        </tr>
        @foreach (var post in Model)
        {
            <tr style="border:1px solid #808080">
                <td>@post.PostId</td>
                <td>@post.Title</td>
                <td>@post.Category</td>
                <td>@post.Content</td>
                <td>@post.UserName</td>
            </tr>
        }
    </table>

</div>

Now we have setup STEP, so let's run the application see what happened. If we run the application, we will see the output as following where we can see the actual data in Table format along with profiling data created by MiniProfiler.

We have clearly see the STEPs[Blue Circled with Image] which we have defined at the time of creating dummy data “Get Blog Post Data” and “Update User Info”. Here we have clear that how much time this application is taken to “Get Blog Post Data” and how much time to “Update User Info”.

MiniProfiler Grouping Test

 

So, based on this profiling reports, we can modify our logic so that our application get, post, update or delete the data in minimum time.

Conclusion

So, today we have seen how to implement MiniProfiler with Asp.Net MVC application and how it can help us to know the actual time taken by each process.

I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks