Swami goes Techie

Here i would share my insights on technologies.

Thursday, September 17, 2009

Friendly RESTful urls, using Http Modules

REST follows

As mentioned in my earlier post(RESTful implementation using .Net) i would like to share further lights on RESTful implementation using .net, this time on implementing friendly RESTful urls using HTTP Modules. On my way to this accomplishment, i was initially doing POCs on HTTP handlers to get the job done and if readers could recollect my questions /doubts that i raised in my previous post(URL Rewriting/Redirecting for Web Service(s) – But How?) regarding the same. At last i found that HTTP modules is the perfect candidate for url redirections and not HTTP handlers.

Friendly REST urls

As an example , for a url, (the below shown url is the same RESTful url, that i had implemented in my earlier post(RESTful implementation using .Net) to get employee details).

http://domain.com/employeeprofile.asmx/GetInfo?empid=1

we can make it user friendly as below,

http://domain.com/employeeprofile/GetInfo/1

i am going take this simple scenario and show how such friendly url rewriting can be implemented using HTTP Modules. Once we get the concept, we can go ahead in developing robust url rewriting engines.

HTTP Module

HTTP Module is one of the extensibility feature and advantage provide in .Net Framework. This helps in intercepting and manipulating each of the http requests that comes  from the client to the server application. Now in order to provide meaningful RESTFul urls, i am going to make use of this advantage provided by the HTTP pipeline. Below diagram describes the HTTP pipeline and the components involved in a typical client server architecture involving .net.

clip_image002

In order to tap the incoming request using http module in our application (Web, Web service, etc) following things are to be performed.

Implementation

1. Creating Http Module class :

Add a normal class file to the application which implements  IHttpModule and its members,

System.Web.IHttpModule.Init(System.Web.HttpApplication)  &

System.Web.IHttpModule.Dispose().

The Init method can be made use to perform  initializations that are required and which also holds the handle to the HttpApplication object which  in turn has control over the request, response objects.

Here in the Init method, i am adding a event handler which processes the application’s begin request event.

public void Init(System.Web.HttpApplication app)
        {
            app.BeginRequest += new EventHandler(Rewrite_BeginRequest);

        }

then in my Rewrite_BeginRequest custom method,  i am adding a simple piece of code,which intercepts the incoming request url, checks for the user-friendly format ( these formats are to be predefined and shared to the consumers of the webs service as some manuals / guidelines, so that they get an idea on how to query for a particular data), if valid,  rewrites the url  to the original page with the desired & required parameters as query strings.

Pseudo code of the Rewrite_BeginRequest(object sender, System.EventArgs args) implementation,

1. Typecast the incoming sender object to the http application object in order to get the handle of request, response, context and other asp.net objects.

System.Web.HttpApplication Appl = (System.Web.HttpApplication)sender;

2. Tap the incoming request url, look for the friendly url pattern "/employeeprofile/GetInfo/”, if valid , crop , validate and store the id part which follows the pattern.(the valid employee id number like 1, 10, etc which comes as part of the ur after the pattern -  "/employeeprofile/GetInfo/1 ) .

3. Now, once the id is retrieved, rewrite the url to the original page by using,

Appl.Context.RewritePath("employeeprofile.asmx/GetInfo?empid=1");

That's it, now the coding for the url rewriting is done. as this is a simple demonstration i have hard-code the urls, but when it comes to real-time implementation we can define the friendly url patterns and their respective redirection urls in some configuration file and create  a url redirection module / library /engine which performs the above pseudo logic.

2. Web Config entry:

Once the coding part is over, we need to configure the custom http module in the web config, hence forth ASP.Net engine recognizes the module and invokes it,

<httpModules> 
<add type="RESTFulService.RESTfulHandlerModule,RESTFulService"      name="RESTFulRewriter" />

</httpModules>

the type attribute, takes in classname, assemblyname as input.

the name attribute is any meaningful name.

I hope this post would be a starter point in the future implementation of a robust URL rewriter engine.

Labels: , , , ,

Thursday, September 10, 2009

URL Rewriting/Redirecting for Web Service(s) – But How?

Getting Started:

I am trying out with a simple URL redirection technique; if I am successful in this approach I will go ahead in implementing friendly RESTful urls for my application. But it’s not happening the way I desired though.

Problem Definition:

I am facing problem in URL redirection while using HTTP handler technique;

I have created a VisualStudio2008 web service application.

Added 2 services, Service1.asmx and Service2.asmx.

Scenario 1:

Added an HTTP handler (GenericHandler) class in the same hierarchy. 

Added the below code in ProcessRequest method,

if (context.Request.PhysicalPath.IndexOf("Service1.asmx") > -1)

                    context.RewritePath("~/Service2.asmx");

Registered the Handler in the HTTP handler section of the webconfig, the bold one

<remove verb="*" path="*.asmx"/>

<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>

<add verb="*" type="RESTWS.RESTHandler,RESTWS" path="*.asmx"/>

Now, I run my application by making Service1.asmx as the start page, the process hits my handler code, executes it with out any exception, but at last I see a blank screen in the browser.

For crossing my code I also did the following,

Scenario 2:

Added a Global.asax file in the in the same hierarchy.

Added same code in Application_BeginRequest

if (Context.Request.PhysicalPath.IndexOf("Service1.asmx") > -1)

                Context.RewritePath("~/Service2.asmx");

Commented out the Handler registry part what I added in the webconfig.

Again ran the application, the redirection from Service1.asmx to Service2.asmx happened successfully as expected.

Scenario 3:

When I have both the Global.asax and the http handler enabled, again I get a blank page.

Scenario 4:

I felt that HTTP handler does not support url redirection in the case of asmx(web services), so I tried the same above procedures and scenarios with VisualStudio2008 Web application with 2 aspx pages (Default1.aspx and Default2.aspx) instead of Web service application. But the results were same as the above scenarios.

My Questions:

What is the mistake I am doing in my above scenarios?

How to perform url redirection for web services using Http Handlers?

Looking fwd:

Some help and suggestions extended in this regard will be greatly appreciated.

Labels: , , , ,