Thursday, February 3, 2011

Asp.net MVP and URL Routing with WebForms. Part1 - The Background


DARE TO SHARE?
Introduction

Lets get back to Asp.net 2.0 days.

One of your clients wants to implement SEO friendly URLs in his/her application. That is, instead of the URLs containing messy query string parameters:

http://www.mysite.com/products.aspx?category=book

He/she wants to see the URLs which look a lot cleaner and more SEO friendly:

http://www.mysite.com/products/book.aspx (No Request parameter)

Or, he/she would be even happier with the following kinds of URLs

http://www.mysite.com/products/book (No Request parameter and no Extension)

Back in Asp.net 2.0 days, How did you implement such a requirement?

Let me answer this for you.

Those days IIS didn't support extension less URLs (IIS 6.0) and Asp.net MVC didn't born yet. So, we had to use the following widely used trick:

URL Rewriting

This trick is usually applied to convert the URLs with Query String parameters to the following types of URLs (Which ends with an extension) in Asp.net applications.

http://www.mysite.com/products/book.aspx

The trick is to intercept each and every Request and use HttpContext.RewritePath(), which does nothing but re-writing (Overwriting) the URL of the current HttpRequest with the original page URL within the current HttpContext, resulting in execution of the original page, instead of the incoming request. The client remains un-aware of this fact because he/she doesn't see and URL change in the browser address bar.

The operation is carried out in following steps:

  • User hits http://www.mysite.com/products/book.aspx in the browser 
  • The request is intercepted at Asp.net and the URL is re-written in the HttpContext pointing to the original page http://www.mysite.com/products.aspx?category=book
  • The original page gets executed and response is being sent to browser, the current URL http://www.mysite.com/products/book.aspx at the browser remains unchanged.

At the very basic level, the following approach is usually being followed:

void Application_BeginRequest(object sender, EventArgs e)
{
  string fullOrigionalpath = Request.Url.ToString();
  if (fullOrigionalpath.Contains("/Products/Books.aspx"))
  {
    Context.RewritePath("/Products.aspx?Category=Books");
  }
  else if (fullOrigionalpath.Contains("/Products/DVDs.aspx"))
  {
    Context.RewritePath("/Products.aspx?Category=DVDs");
  }
}

Some pluggable HTTP Modules are available to implement such URL re-writing in a cleaner and manageable approach, which allows to configure the mappings of incoming URLs to actual URLs using patterns/regular expressions, which is very handy.

Now, what about URLs without any extensions, like the following?

http://www.mysite.com/products/book

Back in Asp.net 2.0 days, IIS 6 didn't support mapping extension less URLs to Asp.net execution engine. So, this had to be done with some tricks to map any incoming Request in IIS (With any extension) to Asp.net by using WildCard setting in IIS.

So, a carefully engineered WildCard mapping with URL re-writing (Along with managing some other issues, such as handling PostBacks, Handling static requests for static resources etc) , it was possible to get the job done, despite the fact that, it wasn't a very easy thing to do.

Asp.net MVC and IIS 7

Well, MVC was totally new. The Model View Control concept was seen to be released as a framework, which allows to de-couple the user interfaces, control application flow with URL Routing and separate data, presentation and business logic using some built-in libraries available in Asp.net, perform unit-tests on the Controller, View and Models, which wasn't easy (Or, wasn't possible) to do so in WebForms. But perhaps the biggest different between the Asp.net WebForm and MVC from end-user's perspective is the extension less URLs which are much SEO friendly, makes more sense to the end-user and which are much cleaner (No URL parameters and no extension if IIS 7 or heigher is used).

Well, the BAD news was, it was no longer possible to use the rich Data bound and other server controls that we used to love so much in Asp.net WebForms. In MVC, there is no Page life cycle, ViewState or server side controls. Just plain basic HTML stuff. Stunning, right?

Yes it was. Despite the fact that Visual Studio does provide a quick start Asp.net MVC application structure with some pre-built Model-View-Controllers (And, some framework classes to do some common stuff easily), being not able to use the server controls any more was seemed to be a real BIG loss. It was kind of sacrificing the productivity and richness of Asp.net WebForms to get URL routing with support of separation of concerns (Model-View-Controller). To lot of people (Specially people like us, the developers), this wasn't really very encouraging.

So, some people thought "How about doing something that allows to get the bests of both world. To be more specific, how about combining the power of URL routing and Separation of concerns (Provided by the MVC concept) with Asp.net WebForm?".

This simple thought gave birth to the concept of Asp.net MVP.

What is Asp.net MVP?

Asp.net MVP stands for Model View Presenter. Its roughly has the same concept that MVC has, with some minor differences (A bit more loose coupling). But, the biggest issue is, unlike the Asp.net MVC, Asp.net MVP is not a framework. Rather, it is nothing but the classic Asp.net WebForm with a conceptual change of working with the components which we are used to work with. In this concept, there will be Models, Views and Presenter where:

Model is the domain or business object which encapsulates data and behavior. Model knows nothing about the two other components View and Presenter.

View is the Aspx and CodeBehind which knows about the Models, and, which doesn't contain any application logic, except displaying data from Models.

Presenter is the glue between the Model and the View, with very loose coupling. It accepts user inputs from the View, determines which business logic to execute and finally sets model to the View so that View can do the rests.

Using the Model View Presenter approach in Asp.net WebForm allows to separate the concerns where the CodeBehinds doesn't contain any business logic, the application flow is controlled by the Presenter and the data is encapsulated by the Models, along with the great advantage of being able to use Asp.net server controls and their immense power to build rich functionality.

So, Asp.net MVP concept allows to build Asp.net applications by using the concept of separating the concerns using the traditional Asp.net WebForms, which is definitely good. But perhaps the most important highlight of Asp.net 3.5 SP1 and onwards is the addition of URL routing facility which allows to map the incoming URL requests to (With the advantage of extension less URL in IIS7 and onwards) any aspx or Controller class, which gives the flexibility of working fully in MVC way with utilizing the full power of Asp.net Web Forms. The URL Routing allows to customize and route the incoming URLs in the same way Asp.net MVC allows to do so, and, the MVP concept allows to implement the application functionality using separation of concerns approach and utilize the full power of Asp.net server controls to build rich user interfaces rapidly.

In the next parts of this article we would explore the URL Routing facility of Asp.net Web Form and utilizing this to develop a simple application in MVP approach. Stay tuned for that.

0 comments:

Post a Comment