Thursday, 19 June 2014

Handler Service for dynamic Javascript

We're creating a great app for photographers to easily sell their works online, with orders fulfilled by the PNI network - how awesome would it be to 'purchase' a print from my dad, and pick it up from Costco? Pretty rad. Especially if all he has to do is drop one line of javascript on his page.

To accomplish it this succinctly I had to build a dynamic javascript page which would allow the intake of an api-key from the users site. Now, I am aware that the big guys at Stack Overflow accomplish this with a JSON object and using StackOverflow.init({JSON_MADNESS}) kind of tag - but I need this to be fool proof and "pretty" so that someone like my dad wouldn't be afraid of it's length. I think this would go a long way to improving uptake. Also, Shane told me I couldn't do it that way. Lousy EA's. So I needed to build a script that would output the required javascript to the users page, why the heck not? Here's the (naive) flow of how I tried to accomplish this:

  1. Append a '?' string of variables to the javascript tag. Immediately dismissed as silly after trying to think of how to get the variables from the js file (uh... location? script name? parsing?). If it could be done, I didn't want to waste time coding it into submission.
  2. Pretty please can I use a JSON object? No? Fine. 
  3. A C# Handler whose call would look like "ourapi.url.com/JavascriptHandler/MrHudsonsAPIKEY" Beautiful; I'd even used an implemented code with our Google Glass app so I'd have a reference application
Here we go. There is, however, a fair bit of trickery involved with C# Handlers (from my perspective, anyway), and getting them to ignore the file extensions. More on that later. First up, lets build the Handler:
  1. Make sure your project solution has the App_Code folder. If not, simply right-click your project name and find the Add > Add New ASP.Net Folder > App_Code
  2. Right-click the App_Code folder and select Add > Generic ASP.NET Handler to create a new file. Call it what you feel appropriate; for my project I called it JavascriptHandler
  3. In the created method stubs, know that ProcessRequest(HttpContext context) is the called method when the user hits the appropriate URL, so this is where your Handler 'starts.'
Modifying the web.config file proved to be a bit of a pain though; all examples that I could find were about modifying incoming files according to their extensions instead of filenames. Essentially, foo.js was easy to redirect to a handler, however, /foo/ was not happening. Here is the web.config content for fixing up foo.js
If you have IIS6.0 (I did not, but that took a bit of fiddling to find out):
<system.web>
  <httpHandlers> 
    <add verb="*" path="foo.js" type="JavascriptHandler"/>
  </httpHandlers>
</system.web>


If you have IIS7.0 You'll notice that the parent node is system.webServer this time:
<system.webServer>
  <handlers>
    <add verb="*" path="foo.js"
        name="JavascriptHandler"
        type="JavascriptHandler"
        allowPathInfo="true"/>
  </handlers>
</system.webServer>

If you want to know more about what verb, path, type all mean, read the Microsoft documentation (sorry, can't find the exact link at the moment).

I found that if I removed the '.js' file extension, I would get an error page saying "JavascriptHandler not found in this assembly" but it -had- to happen that way... So I queued the music, and got to work.

I eventually found a blog post on exactly what I needed: "Extension-less Routing" This resource and explanation is so well put and apparent (after the fact) that I will leave it up to you to read and enjoy. Spoiler alert: It's a bug in IIS of the mappings of "*." Kind of takes the edge of spending the morning on this.

tl;dr - To get a url like www.example.com/FooHandler/ to run a Handler, go here and apply the hotfix.

Till next time - Find me on Twitter to say hello and ask a question about my ongoing developments

No comments:

Post a Comment