With Visual Studio 2010, Microsoft is shipping the next version of the popular ASP.NET MVC Framework with its IDE. A year ago I blogged about my findings when getting my hands on the first version of ASP.NET MVC. The MVC Framework provides really nice features that make it very easy to build web applications on top of ASP.NET. The updated support in Visual Studio also makes it very appealing to choose MVC instead of traditional ASP.NET.
The most important thing about using any framework is to understand its internals. Without that knowledge you easily run into the problem of using the framework in an unintended way resulting in problems down the road that might be hard or impossible to fix. Therefore I am going to start a series of blog posts, analyzing the internals of ASP.NET MVC 2 with the intention to educate us all about what is going on behind the scenes in order to build better applications – sounds like a plan? 🙂
There are two key takeaways in this post that hopefully make you decide to read to the very end:
a) Enable Client Side Validation to reduce network roundtrips
b) Make sure you deploy your app without any debug switches on
Create a new ASP.NET MVC 2 Application
First of all you need Visual Studio 2010. It seems Microsoft offers it in a Trial version on their Visual Studio MSDN Page. Once you have it installed go ahead and create a new ASP.NET MVC 2 Application:
The project wizard will prompt you whether to create Unit Tests for your MVC Controller classes. Great to see that testing is really taken more seriously and that Visual Studio supports us with ensuring good test coverage 🙂
The template project comes with two controllers (Home and Account) and also implements a membership service to deal with users that can logon to our site. The database used to store the account information is configured in the web.config file. By default the AspNetSqlMembershipProvider is used that stores information in a SQL Express Database. One new thing in VS2010 is that besides having one web.config file you can have a web.config.debug and web.config.release file. These configuration-specific files allow you to run transformations on the original web.config file to e.g.: get rid of debug settings.
Basically we are ready to go and launch the application – just Hit F5. You will notice that Visual Studio – when launching a Web Application from within the IDE – will use a standalone Development Web Server (WebDev.WebServer40.exe). The Web Server adds an icon to the system tray, and from there allows you to browse to the main page or simply stop the web server at any time.
Exploring the Application – Walking through a simple scenario
The second thing I need to analyze Server-Side activity is a tool that allows me to trace the executed .NET code while I browse through the web site. I am using Dynatrace with the ASP.NET MVC FastPack that gives me all I need to get a Quick Start on analyzing everything going on within my application. I also use the dynaTrace Visual Studio 2010 Add-In that eliminates some configuration steps when launching an application from Visual Studio. Now let’s get started.
Step 1: Launch the Application
Either launch it in debug mode or – like in my case – launch it with Dynatrace support:
After the application is launched we see the ASP.NET Development Server in the tray icon. The details show us which web site is hosted on which port:
Step 2 – Walking through a Use Case Scenario
Alright – let’s walk through the following use-case scenario to test the user management feature of the out-of-the-box implementation of our ASP.NET MVC 2 Application. I click on [Log On]. I enter a bogus user name password combination to test whether I cannot just logon. Yeah – seems I cannot logon as I get the message that my login was unsuccessful with the provided username and password. Let’s click on Register to register a new account. In my first attempt I enter a too-short password then a non matching password and confirm password. The App shows me errors -> just as expected. I try it again with correct input values – voila – works :-). I finish my use case by clicking on Home, About and then [Log Off].
Analyzing the Browser Activities – ENABLE Client-Side Validation to improve performance
The key takeaway here is to make use of the client-side validation feature. It results in a more interactive user interface, reduces round-trips to the server, and therefore frees resources on the server for more important work.
Analyzing Server-Side Activities – Don’t forget to TURN OFF debug compilation
Starting from the AJAX Edition Network View I pick the request of my first use case walkthrough where I used a non existing username and password on the logon page:
Drilling to the Server-Side PurePath allows me to see the full execution trace of this particular request to explore a) what is really going on in the page life-cycle of my ASP.NET MVC 2 Application and b) why this took 1.8seconds:
The PurePath shows how ASP.NET MVC starts by creating the Controller – in our case it is the Account controller and invokes the LogOn action that verifies the passed logon credentials. The slowest method in the execution trace is LogOn which takes 1.4s. The reason why it is that slow is because this is the first time the database gets accessed – we can see that in the two thrown exceptions in the beginning. This method then calls the stored procedure dbo.aspnet_Membership_GetPasswordWithFormat and passes the 5 parameters to it as can be seen in the Details dialog of the SQL Statement:
The password verification fails and therefore the Account controller sets a Model Error to indicate the problem of an incorrect password. This causes the Controller to default back to the LogOn view instead of being redirected to the Home View.
After the controller returns, ASP.NET continues “normally” and starts rendering the LogOn View as requested by the Controller. The interesting detail here is that when using the RenderPartial method the ASP.NET MVC framework internally browses through different directories to find the user control. In debug mode this lookup happens every time – even when the control has already been looked up causing a huge number of internal hidden exceptions. The reason why I stress this fact is because it is just too easy to forget to turn off the debug compilation switch in the web.config file. I know – it should not happen – but, I do have several stories where this has happened. For more details on this check out my post on Hidden Performance Problems with HtmlHelper.RenderPartial I wrote about a year ago.
Next: Getting deeper into ASP.NET MVC
That’s it for the first blog of this series. I will continue to extend the default ASP.NET MVC and explain more of its internals. I will also focus on memory analysis in .NET in general. My colleague Alois already wrote several nice articles about Memory Leak Detection in Java – now it is time to catch up with him and provide helpful hints for my fellow .NET folks 🙂
The used Dynatrace ASP.NET FastPack and the Visual Studio Add-In can be downloaded by Dynatrace users on the dynaTrace Community Portal. For all others – if you are interested in more details check out the White Paper I wrote on Performance Management in Enterprise .NET Systems. Stay tuned.