70-486.C4.Troubleshoot and debug web applications

CHAPTER-4.Troubleshoot and debug web applications

Objective 4.1: Prevent and troubleshoot runtime issues

Troubleshooting performance, security, and errors

Using Performance Wizard

Profiling is the process of analyzing a running computer program.

Performance Wizard provides several different profiling methods:

  • CPU sampling
  • Instrumentation
  • .NET memory allocation
  • Resource contention data

CPU sampling gathers information every few CPU cycles about the work occurring in the computer. It acts more as an initial check, providing direction about where you need to further examine the system.

Instrumentation enables you to better understand the source of performance problems.

.NET memory allocation analyzes every object in memory from creation to garbage collection.

Resource contention data provides information on how your threads interact with each other and with the system, CPU utilization, overlapped input/output (I/O), and many other useful metrics when trying to determine why your multithreaded application does not perform properly.

Using Visual Studio Profiler

Profiler performs a complete trace of the calls that occur in an application.

Using Performance Monitor

Performance Monitor has hundreds of individual monitors, several of which are specific to ASP.NET.

System performance counters focus on application and process start and stop and running applications, whereas application performance counters watch details going on within the application such as requests, caches, and application errors.

You can schedule the time when you want performance monitoring to run.

Troubleshooting security issues

Generally, security issues tend to be related to authentication and authorization.

Implementing tracing, logging, and debugging

NLog and log4net are two well-known open-source logging tools.

Tracing is a technique that enables you to analyze your application while it is running. It is a built-in feature of .NET Framework.

The easiest way to configure a TraceListener is through the Web.config file, as follows:


Error logging can also be handled automatically by using the HandleErrorAttribute, by overriding the controller’s OnException method, or by using a custom error filter. The HandleErrorInfo class contains details about the exception that needed to be managed as well as information about where the error occurred. Using the HandleErrorAttribute does not pass information through a controller, which is unnecessary. You can handle errors at the controller level by overriding the controller’s OnException method.

LISTING 4-1 An example of overriding the OnException method in a controller

protected override void OnException(ExceptionContext exceptionContext) 
    if (exceptionContext.IsChildAction) 
        //we don't want to display the error screen if it is a child action, 
    // log the exception in your configured logger 
    //handle when the app is not configured to use the custom error path 
    if (!exceptionContext.HttpContext.IsCustomErrorEnabled) 
        exceptionContext.ExceptionHandled = true; 

You can manage exceptions at a more global level through the Application_Error method in the Global.asax file. It is typically used for logging and tracing the thrown exception.

Enforcing conditions by using code contracts

Code contracts involve:

  • Preconditions
    Conditions that have to be fulfilled before a method can execute.
  • Invariants
    Conditions that do not change during the execution of a method.
    Conditions that that are verified upon completion of the method.

Contracts are a way for you to codify your dependencies and enable them to be visible by the consumers of your methods.

LISTING 4-2 Parameter checking

internal Article GetArticle(int id) 
     if (id <= 0) 
         throw new ArgumentException("id"); 
     // some work here 

Using contracts to perform this check enables consumers of the methods to get some information about the expectations of the method:

internal Article GetArticle(int id) 
    System.Diagnostics.Contracts.Contract.Requires(id > 0); 
    // some work here 

An invariant contract is designed to ensure that a class does not become invalid during processing, except during brief private calls for transactional work.

Enabling and configuring health monitoring

Health monitoring is a subsystem built into ASP.NET that is specifically designed to handle logging of various web events such as application lifetime events, security events, and application errors. It is part of the ASP.NET framework so it has default access to more events than most third-party logging providers. It follows the Microsoft provider framework, so it can be added to your application through configuration.

Objective 4.2: Design an exception handling strategy

Handling exceptions across multiple layers

A layer should know only about the layer it communicates with, and it should have no knowledge about layers that might be calling it.

Displaying custom error pages, creating your own HTTPHandler, and setting Web.config attributes

The Global.asax page is one of the ways you can support custom error pages.

LISTING 4-4 Managing errors using the Application_Error method

public void Application_Error(Object sender, EventArgs e) 
    if (Server != null) 
        //Get the context 
        HttpContext appContext = ((MvcApplication)sender).Context; 
        Exception ex = Server.GetLastError().GetBaseException(); 
        //Log the error using the logging framework 
        //Clear the last error on the server so that custom errors are not fired 
        //forward the user to the error manager controller. 
        IController errorController = new ErrorManagerController(); 
        RouteData routeData = new RouteData(); 
        routeData.Values["controller"] = "ErrorManagerController"; 
        routeData.Values["action"] = "ServerError"; 
            new RequestContext(new HttpContextWrapper(appContext), routeData)); 

You can also set error information in the Web.config file by adding error nodes to the section of the area. The following example redirects the appropriate status code to the indicated URL:


You must set in the section of Web.config as well.

HTTP 500 errors are generally handled through other means than configuration, such as filters or OnException handlers.

Handle first chance exceptions

First chance exceptions are exceptions before they have been handled by an error handler. Every error that occurs in an application begins the error-handling process as a first chance exception.

LISTING 4-5 Capturing first chance exceptions in code

protected void Application_Start() 
    AppDomain.CurrentDomain.FirstChanceException +=  
protected void CurrentDomain_FirstChanceException(object sender,  
         System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e) 
    if (e.Exception is NotImplementedException) 
        // do something special when the functionality is not implemented 

Objective 4.3: Test a web application

Creating and running unit tests

Unit test your code

Creating mocks

A shim is a small piece of code that intercepts a call to an assembly and has it return an object you created, or mocked.

A stub is code that replaces a working class with a limited subset of a class you mocked up.

Shims are generally used to provide mocks from assemblies outside of your solution, whereas stubs are used to create mocks of classes within your solution.

Create and run web tests

Types of load tests

There are three different approaches you can take when running load tests: constant, step, and goal-based.

Constant load tests enable you to set a constant number of users. The testing process uses the same users through the entire test run.

The step load test steadily adds users to the testing process. There are four values you
need to consider when using a stepped performance testing approach:

  • Initial user count
    The number of users that start as soon as the testing process starts
  • Maximum user count
    The maximum number of users to be used in the process
  • Step duration
    The value, in seconds, of the time between the start of each new group of users
  • Step user count
    The number of users to be added after the expiration of each duration

Goal-based load test uses the user count as a way of getting to other goals, including percent of CPU usage and percent of memory usage.

Test planning

Four primary types of test approaches:

  • Smoke
  • Stress
  • Performance
  • Capacity planning

Objective 4.4: Debug a Windows Azure application

Collecting diagnostic information

The customized diagnostic tools are bundled in the Microsoft.WindowsAzure.Diagnostics namespace, which is contained in the Windows Azure Software Development Kit (SDK).

LISTING 4-11 Adding diagnostics to the ServiceDefinition.csdef file


A sample of Windows Azure diagnostics configuration code in the Diagnostics.wadcfg file


There are two ways to transfer this information to a Windows Azure Storage Account: ondemand and scheduled. The on-demand approach requires that code within your application, within the role, or from an external application requests the transfer. The scheduled transfer is set up during the configuration of the log directory.

Debugging a Windows Azure application

There are two options for debugging an application in Windows Azure: IntelliTrace and RDP.

IntelliTrace traces through the mechanics of a running application.