Wednesday, October 20, 2010

Implementation of the Portal Independency feature using Http Handlers

Introduction
An often overused and hyper sensitized word in most web application development projects is the term “Client Usability”. A natural offshoot of this is the need/urge for personalization, wherein the end user wants to apply the look and feel of the web application he is currently using to all the websites he can deep link into. This is similar to the Themes feature we get to see in most of the popular social networking and e-mail sites.
HTTP Handler is a new feature offered by ASP.NET. The HTTP handler module acts as an intermediary between the web server and the client. This module can be configured to intercept particular URL signatures and perform actions on them selectively. The common areas where this can be used are –
1. Security – Filter out requests from clients for selected websites.
2. Custom styles and Images – Allow users to define and apply their own styles and images.
3. Logic Pre-processing and Logging – Implementing Logic “on the fly” and providing logging information for the application.

Requirement in "All-In"
The Portal independency is a new feature in the "All-In" which is designed to provide clients the luxury of applying their own custom look and feel to the "All-In" site. Common example for the usage would be a Department X wants to display the top banner and the Logo of the parent site from which the user invokes the "All-In" Application; this would then enable the Department to seamlessly integrate "All-In" (or specific web pages) within its own parent site.
Implementation
Http Handlers implement the System.Web.IHttpHandler interface. Any class that implements the IHttpHandler interface can act as a target for the incoming HTTP requests. The IHttpHandlers requires implementation of 2 methods: ProcessRequest and IsResusable.
ProcessRequest – This is like the Page_Load event of the handler. All the logic for processing the Request and modification of the Response can be included in this method. In other words, this is where all the action takes place.
IsReusable – This property is called to determine whether this instance of the http handler can be reused for fulfilling other requests of the same type. HttpHandlers can return either true or false for this property.

Registering HTTP Handlers in Config Files – The HTTP Handler configuration information tells the ASP.NET runtime the nature of the files for the Handler to intercept. This is maintained in the web.config of the web application. The files listed in this section would be eligible for interception by the custom handler.
We can use and nodes for adding HTTP handlers to our Web applications. In fact the handlers are listed with nodes in between and nodes. Here is a generic example of adding an HTTP handler:

httphandlers>
add path="path" type="namespace.classname, assemblyname" verb="supported http verbs">
/httphandlers>

Note: The start angle brackets for HTML are deliberately missed as they were causing a problem in rendering of the blog text.

In the above XML,
The verb attribute specifies the HTTP verbs supported by the handler. If the handler supports all of the HTTP verbs, simply use "*", otherwise list the supported verbs in a comma separated list. So if your handler supports only HTTP GET and POST, then verb attribute will be "GET, POST".
The path attribute specifies the path or wildcard specification of the files for which this handler will be invoked. For example, if you want your handler to be called only when test.xyz file is requested, then the path attribute will contain "test.xyz"; similarly if you want your handler called for any file having .xyz extension, the path attribute will contain "*.xyz".
The type attribute specifies the actual type of the handler or handler factory in the form of a combination of namespace, class name and assembly name. ASP.NET runtime first searches the assembly DLL in the application's bin directory and then searches in the Global Assembly Cache (GAC).
An interesting aside to Http Handlers is that the ASP.NET runtime uses it for implementing a lot of its own functionality. ASP.NET uses handlers for processing .aspx, .asmx, .soap and other ASP.NET files.

Algorithmic Approach for Portal Independency using Http Handlers:
In "All-In", all the GUI design i.e., the layout of all the ASP.NET Web pages (.aspx) is developed as a part of a well defined architecture. One of the pre-requisites for the implementation is that the end user of the feature should override the existing classes of the stylesheets so as to maintain the consistency and screen logic. The end user is free to change the logo and contents of the styles as per his requirement.
1. The styles would be stored in the Database tables, hence associate a unique style identifier ID (text ID) for each user.
2. The Stylesheet and the images would be stored in the Database and would be retrieved by this unique identifier.
3. Create a Class which implements the IHttpHandlers interface. In case maintaining a Session state within the HTTPHandler is a requirement, then the IRequiresSessionState interface should also be implemented. If a handler requires only Read access to the session data then it should only implement the IReadOnlySessionState interface.
4. Within the ProcessRequest method, the HTTP Handler has access to all the ASP.NET intrinsic objects passed to it in its parameter through the System.Web.HttpContext object. Implementing the ProcessRequest method is simply extracting the HttpResponse object from the context object and then sending some HTML out to the client. Similarly, IsReusable returns true to designate that this handler can be reused for processing the other HTTP requests.
5. In this method retrieve all the associated styles for the particular request identifier and write it to the corresponding HTTP Response. This would result in the styles getting rendered along with the output page HTML.
6. Include Caching of styles in the code so that the same styles are retained in Session as the user navigates through each page of "All-In".
7. In the web.config file, include the signature of the URL for which the HTTP handler would be triggered. Here one could create a custom URL signature like FolderName/Unique Style ID/*.aspx.
8. Make modifications to the Master Page of the application such that in case the request URL contains the style sheet identifier then include logic to create the custom signature URL which would in turn trigger the HTTP Handler.

Conclusion
The feature of Http Handlers gives more control to the developer wherein he can code and plug in his own components into the ASP.NET request processing pipeline. The security feature is simplified to a great extent and the developer no longer has to write complex components in C/C++ and host them in ISAPI filters and extensions to provide custom request handling. Happy Coding.

Saturday, October 16, 2010

De-Linking LINQ

For learning LINQ the best option is to check MSDN for references and then experiment.For days I was mystified with LINQ. How does it perform? One of the interesting features, that I found out is deferred execution of LINQ. So I decided to put forward some experimental program to test out the performance of LINQ and foreach construct. I have considered a load of 50000 records in the list of Objects. So here goes the code that I used:

Test Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Wonder
{

/*Main Console Program For Testing Performance of LINQ and ForEach*/

class Program
{
const int LIMIT = 50000;
static SourceRecordList recordSet = new SourceRecordList();
static SourceRecord record;

static void Main(string[] args)
{
LoadData();
TestLinq();
TestForEach();
}

static void LoadData()
{
/*Load Data*/

for (int index = 0; index <= LIMIT; index++)
{
record = new SourceRecord(index, "Data" + index.ToString(), LIMIT - index, true);
recordSet.Add(record);
}
}

static void TestForEach()
{
for (int index = 0; index <= LIMIT; index++)
{
Stopwatch timeTracker = new Stopwatch();

if ((index == LIMIT || index == LIMIT / 2 || index == 1))
{
/*Testing Performance of For Each Loop in Finding Records, without breaking from Loop*/

bool found = false;
timeTracker.Reset();
timeTracker.Start();
foreach (SourceRecord recordItem in recordSet) { if (recordItem.ID == index) { found = true; } }
timeTracker.Stop();
Console.WriteLine("Using ForEach (Without breaking From Loop) Searched " + index.ToString() +
" in " + timeTracker.ElapsedTicks.ToString() + " ticks");

/*Testing Performance of For Each Loop in Finding Records, breaking from Loop, once found*/

found = false;
timeTracker.Reset();
timeTracker.Start();
foreach (SourceRecord recordItem in recordSet) { if (recordItem.ID == index) { found = true; break; } }
timeTracker.Stop();
Console.WriteLine("Using ForEach (Exiting loop, once found) Searched " + index.ToString() +
" in " + timeTracker.ElapsedTicks.ToString() + " ticks");
}
}
Console.ReadLine();
}
static void TestLinq()
{
for (int index = 0; index <= LIMIT; index++)
{
Stopwatch timeTracker = new Stopwatch();
if ((index == LIMIT || index == LIMIT / 2 || index == 1))
{
/*Testing LINQ performance for building Expression Tree*/

timeTracker.Reset();
timeTracker.Start();
var searchResult = from recordItem in recordSet where recordItem.ID == index select recordItem;
timeTracker.Stop();
Console.WriteLine("Expression Tree built in:" + timeTracker.ElapsedTicks.ToString() + " ticks");

/*Testing LINQ performance for executing same LINQ first time*/

timeTracker.Reset();
timeTracker.Start();
Console.WriteLine("First Execution of LINQ to Find " + searchResult.First().ID.ToString() +
" in " + timeTracker.ElapsedTicks.ToString() + " ticks");
timeTracker.Stop();

/*Testing LINQ performance for executing same LINQ second time*/

timeTracker.Reset();
timeTracker.Start();
Console.WriteLine("Second Execution of LINQ to Find " + searchResult.First().ID.ToString() +
" in " + timeTracker.ElapsedTicks.ToString() + " ticks");
timeTracker.Stop();
Console.ReadLine();
}
}
}
}
}

Entity:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wonder
{

/*Data Structure Used For Demonstration*/

public class SourceRecord
{
public int ID { get; set; }
public string Name { get; set; }
public int DisplayOrder { get; set; }
public bool IsValid { get; set; }

public SourceRecord(int id, string name, int displayOrder, bool isValid)
{
ID = id;
Name = name;
DisplayOrder = displayOrder;
IsValid = isValid;
}
}

public class SourceRecordList : List
{
}
}

The execution result seemed interesting as well. You should try out this sample or experiment out yourself, but it is really worth conducting the performance test, which reveals many stories and faces of the mystified LINQ in action.

There are multiple opinions and people have concluded in multiple ways, for this loved and hated deferred execution feature of LINQ. I would rather leave space for thought for the reader and would just say that "Think before you use LINQ"!!


See http://msdn.microsoft.com/en-us/netframework/aa904594.aspx for learning references on LINQ.


Thursday, October 7, 2010

Debugging

"… when you have eliminated the impossible, whatever remains, however improbable,must be the truth?”

- Sherlock Holmes (Sign Of Four)

The age old theories used by crime detectives are no less applicable to the modern day geeky act of debugging. Debugging starts with suspecting everyone in the premise and gradually eliminating each probable in the list of suspects. All said and done, the actual problem lies in identifying the right premise and short listing the suspect root causes.

All defects fall in two categories, one which is reproducible in all environments and one which is not. In the first case, it is more often than not, related to whatever stays constant between the environments (code) and in the second, invariably towards environment dependent settings (configuration values, software version/patch, hardware specifications, memory, firewall, data, incorrect deployment etc).

Ruling out options without enough evidences is a grave sin in debugging. One may always start with ruling out the simpler to validate probable, which is more methodical and safer to approach. One can also choose to rely on their sixth sense, hunch and experience (ability to relate to past incidents) to pick the validation sequences,which at times prove to be the quickest debugging approach. The flipside is that if your hunch fails, this approach often becomes annoyingly lengthy for a simple defect.

The modern day development environments have state of the art support for integrated debugging tools catering to various debugging needs. (See Visual Studio /Eclipsedocumentations on Debugging Techniques)

One of the important aspects of debugging in production or similar environments with limited access to real-time debugging is to build plenty of instrumentations/logging(See Instrumentation Options in .Net/Logging Application Block/Java Logger API/Log4J)around the code. For ASP.Net applications, one can leverage ASP.Net tracing feature to have a runtime diagnostic ability, which needs to be handled carefully for space constraints.

For runtime diagnostic, one may also resort to an appropriate application/ runtime profiler. (See CLR Profiler, SQL Server Profiler, ANTS memory Profiler). Another interesting tool is .Net Reflector PRO, which lets you seamlessly debug assemblies without source.

Equally important in debugging is having a consensus on whether a defect is repeatable or not and historically this has been the most painful aspect. Of late, we have a number of options where with different Test Suites are addressing this point by providing Test Recorders and easy simulation of the scenario. (See what’s new in VSTS 2010 for Testers, Test Manager Integration with Rational Functional Tester)

Network Traffic Flow can be visualized and monitored through a tool called FlowScan which produces graphical images that provide a continuous, near real-time view of the network border traffic.

Equipped with all the tools and techniques, one still faces challenges in debugging primarily due to jumping into conclusions with inadequate analysis of available information and lack of patience in case of hard to debug/ weird defects.

Self nurturing is very important, as with experience, intuition, diligence and faith,one gets the best debugging tool within one’s self.

Happy Debugging!