Monday, August 1, 2011

Write custom ASP.NET HTTP Handler using JavaScript

JavaScript is extremely popular language and already has implementations for server-side programming. For example Node.js  - a server-side JavaScript environment that utilizes Goggle's V8 JavaScript Engine.


I am an ASP.NET developer and want to use JavaScript in the ASP.NET environment. I found Javascript .NET project, that bring Google's V8 to the .NET world and I started with a simple task - to write a custom ASP.NET HTTP Handler using JavaScript. (I had done similar task with IronPython before)




Setup requirements

1. I want *.js file to be processed on server (like *.aspx or *.ashx)
2. I want to access server side objects (such HttpContext, HttpRequest and HttpResponse) from javascript code.

Implementation

First of all, download Javascript .NET and add the reference to Noesis.Javascript.dll. It embeds Google's V8 and contains an API required to run JavaScript code



Setup custom HTTP Handler in web.config. It will handle any request of *.js file under App folder. I configure it this way to allow other javascript files (not under App folder) to be processed as static content for being used in browser.


Next step - create App folder and  HelloWorld.js file:



Write the single line code:


At this moment I expect this code run on server and produce simple 'Hello World!' html.
But to make it works I have to implement JavaScriptHttpHandlerFactory - the core of all this.

JavaScriptHttpHandlerFactory

Implementation is listed below:


using System.IO;
using System.Web;
using Noesis.Javascript;

namespace Web
{
    public class JavaScriptHttpHandlerFactory : IHttpHandlerFactory
    {
        public IHttpHandler GetHandler(HttpContext context, 
                   string requestType, string url, string pathTranslated)
        {
            return new JavaScriptHttpHandler(pathTranslated);
        }

        public void ReleaseHandler(IHttpHandler handler)
        {
        }
    }

    public class JavaScriptHttpHandler : IHttpHandler
    {
        private readonly string pathTranslated;

        public JavaScriptHttpHandler(string pathTranslated)
        {
            this.pathTranslated = pathTranslated;
        }

        public void ProcessRequest(HttpContext context)
        {
            var scriptCode = File.ReadAllText(pathTranslated);

            using (var jsContext = new JavascriptContext())
            {
                jsContext.SetParameter("context", context);
                jsContext.SetParameter("request", context.Request);
                jsContext.SetParameter("response", context.Response);

                try
                {
                    jsContext.Run(scriptCode);
                }
                catch (JavascriptException ex)
                {
                    throw new HttpParseException(ex.Message, ex, 
                      pathTranslated, scriptCode, ex.Line);
                }
            }
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }
}

As you may see, implementation of JavaScriptHttpHandlerFactory is pretty simple. Read the js file, create JavascriptContext, setup context parameters and finally execute.

Now when you run HelloWorld.js you get "Hello World!" in browser:


Error handling

But all of this worth nothing if we are not able to debug javascript easily.
Javascript.NET allows us to handle javascript errors and even points to source code line where error was occurred.

I used this feature to expose a javascript error in convenient format of "yellow screen of death":




Conclusion

Integration of JavaScript into ASP.NET environment is possible and not so hard

BTW, Javascript.NET is not only technology allows it. There is IronJS wich runs javascript over DLR. May be in one next posts will play with it.