Web Widgets with .Net : Part One

Web Widgets with .Net : Part One

This two part article is based on a presentation I gave at Tech Ed North America, Developers Week, 2008, about using .Net to create Web Widgets for the MSDN and TechNet sites. Part one will cover the creation of a basic widget, written in C# and JavaScript. Part two will update that widget to be more dynamic using C#, LINQ, JavaScript, JSON (JavaScript Simple Object Notation), and CSS.

Web Widgets : A Simple Definition

The best place to start is to give you a definition of Web Widgets. From Wikipedia.org, the following is a good description: “(a web widget) is a portable chunk of code that can be installed and executed within any separate HTML-based web page by an end user without requiring additional compilation.”

The basic idea is that a consumer site only needs to deploy a simple script block which requires no compilation. We achieve this by setting the script block’s source (src) parameter to a Uri on a separate widget host server. All server side processing is done on the host server, which sends back client-side script to render the widget on the consumer. There are probably hundreds of possible ways to build a Web Widget, but I’m going to walk through one specific example using .Net.

Typically, Web Widgets can be consumed on any domain outside the host domain. However, Browser Cookie data is available in the Request if in the widget is deployed within the same domain as it is hosted. Additionally, Request information such as Server Variables and QueryString are available in any domain.

Let’s Write Some Code : A Basic Widget using an HttpHandler

Now that we’ve covered some background about what we are building, let’s get to work. As I mentioned before, we are going to be using C# and JavaScript to build this. You could really use any .Net language for the Middle-Tier, but I found that the syntactical similarities between JavaScript and C# made switching gears between the two tiers a bit less jarring.

The code for this first example can be downloaded here: https://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=webwidgetsdotnet&DownloadId=2330

 

Step 1 : Create an HttpHandler Base Class for all widgets to use.

First, let’s create a base class that can be used for multiple widgets. It will handle the basic functionality of an HttpHandler. Note: I chose to use an HttpHandler here in order to avoid the overhead of the ASP.Net Lifecycle. There is no need in this pattern to use Viewstate, Page Events, or Postbacks, so I can avoid all the unnecessary overhead by using an HttpHandler.

1) Create a new Visual Studio C# Web Project and call it “Demo1”

2) Add a new directory called Handlers and add a WidgetBase.cs class file inside this folder. Mark that class as abstract since it will be our base class.

3) Implement the IHttpHandler interface

4) Using the VS2008 IntelliSense context menu, stub out the required members for an HttpHandler

 

 

 

 

 

 

This will add the following interface members…

IsReusable - property to let IIS know whether this handler can be re-used by other threads.

ProcessRequest(HttpContext context)- The main method of a handler. This is where we will do the work to write a response to the browser.

5) Set IsReusable to return false to ensure thread safety – We don’t want any other requests to come in and modify variables

6) Add null reference checks to ProcessRequest, to avoid null reference exceptions

if (context != null && context.Request != null && context.Response != null)

{

7) Add an abstract BuildOutput() method that returns a string. We want to force inheritors to use this method.

 

public abstract string BuildOutput();

8) Add a member variable to hold a reference to the HttpContext object that is passed into ProcessRequest

   

    private HttpContext _context;

 

9) Response.Write the results of BuildOutput in ProcessRequest, using the Response object in the _context member variable just added in step 8.

_context = context;

_context.Response.Write(BuildOutput());

 

10) Add Request and Response shortcuts, using _context member variable. We will be using these shortcuts later, in the widgets that use this base class.

/// <summary>

/// Shortcut to Request object

/// </summary>

public HttpResponse Response

{

    get { return _context.Response; }

}

/// <summary>

/// Shortcut to Request object

/// </summary>

public HttpRequest Request

{

    get { return _context.Request; }

}

That is all the work we need to do in WidgetBase for now. Let’s move on to create a object of type WidgetBase.

Step 2 : Create an EventsWidget class and wire up the handler in IIS

1) Add a new class file called EventsWidget.cs to the Handlers directory

2) Implement the WidgetBase class and stub out the BuildOutput method using the handy VS2008 Intellisense dropdown

3) Create and return a string called “output” in the BuildOutput method and initialize it to the common “Hello World!” value, since this is the first time we’ll run this application.

public override string BuildOutput()

{

    string output = "Hello World!";

    return output;

}

4) Open an IIS Management Console and navigate down the application you are running this project in. (Create an application if you haven’t already)

5) In the application configuration features view, look for the “Handler Mappings” feature and double click it to see a list of existing handlers.

6) In the “Actions” area of this view, click the link to “Add Managed Handler”

7) Set up the new Managed Handler similar to the settings below.

Managed Handler Screenshot

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Request Path: eventswidget.jss

Type: Demo1.Handlers.EventsWidget

Name: EventsWidget

8) The handler should be ready to run now, so let’s check it in a browser. Open up your favorite browser and navigate to the application you’ve been working in. Add the request path you created in step 7 above to the URI to hit the handler you’ve created. You should see a friendly “Hello World!” message on the screen.

Step 3 : Modify the HttpHandler to output JavaScript

1) Add a new directory called “templates” to hold script templates, and add a new file called core.js. This file will be used as a utility class to hold functions common to widgets.

2) Open /templates/core.js and add the following code to setup a namespace, constructor, and class definition for an object called Core. (Note: you should modify the namespace to match your own company or team)

/** Microsoft.Com.SyndicationDemo.Core.js: shared functionality for widgets **/

// Namespace definition : All Widget Classes should be created in this namespace //

if (!window.Microsoft)

  window.Microsoft = {};

 

if (!Microsoft.Com)

  Microsoft.Com = {};

if (!Microsoft.Com.SyndicationDemo)

  Microsoft.Com.SyndicationDemo = {};

 

// Widget Core Constructor //

Microsoft.Com.SyndicationDemo.Core = function(message)

{

     document.write(message);

}

// Widget Core Class Definition //

Microsoft.Com.SyndicationDemo.Core.prototype =

{

}

var core = Microsoft.Com.SyndicationDemo.Core("Hello from JS!");

 

The above JavaScript code is using a feature of the JavaScript language to create a class definition, called Prototype-based Programming. When we “new” up a version of this Core object, it will run the code in the constructor and write out a message via JavaScript.

3) Add a method to WidgetBase which will allow us to read the contents of the JavaScript file we just created. Modify WidgetBase.cs by adding the following method:

        public string ReadFromFile(string fileName)

      {

            string fileContents = string.Empty;

            if (HttpContext.Current.Cache[fileName] == null)

            {

                string filePath = HttpContext.Current.Server.MapPath(fileName);

                if (File.Exists(filePath))

    {

                    StreamReader reader;

                    using (reader = File.OpenText(filePath))

                    {

                        fileContents = reader.ReadToEnd();

                    }

                }

                HttpContext.Current.Cache.Insert(fileName, fileContents, new System.Web.Caching.CacheDependency(filePath));

            }

            else

            {

                fileContents = (string)HttpContext.Current.Cache[fileName];

            }

            return fileContents;

        }

4) Modify EventsWidget.cs to read the JavaScript file using the method we just created. Change the content of the BuildOutput() method to the following:

string output = base.ReadFromFile(ConfigurationSettings.AppSettings["CoreJavascriptFileName"]);

return output;

5) Lastly, lets hook up this handler in a script block so that it actually runs in a script context. Add a new file called default.aspx to the root of the application. This file will serve as a test harness for our widgets. Add the following script block to the new page:

<script type="text/javascript" src="eventswidget.jss">

        </script>

6) At this point, we can now hit the new default.aspx in the browser. It should display a friendly message from JavaScript. If you do not see any message, try hitting the handler directly to see if it is throwing an error.

In part two of this article, I will use this project as a starting point and make it dynamic. Part two will cover accessing data, passing data to JavaScript, and working with Styles via CSS.