My first WebORB for .NET app, as is traditional, simply displays the message “Hello, World!” — but with a client/server twist.
The server side code is implemented as a C# class library:
using System;
using System.Web;
namespace HelloWorldServer
{
public class HelloWorldService
{
public string getHelloString()
{
return "Hello, World!";
}
}
}
Compiling that in VisualStudio 2008 produces an assembly called “HelloWorldServer.dll”, at \Visual Studio 2008\Projects\samples\HelloWorldServer\HelloWorldServer\bin\Debug.
[Why VisualStudio 2008 instead of VisualStudio's new, über-cool 2010 version? Because, as a former Microsoft employee, I can buy Visual Studio 2010 Professional super-cheap through the Microsoft Company Store...but it's on back-order there now. Until it's back in stock, I'll stick with the older version.]

One way to make this service available to WebORB for .NET clients is to copy the service’s DLL into WebORB’s \bin directory. For my installation, that’s C:\Program Files\WebORB for .NET\4.0.0.5\bin; your mileage may vary, depending on where you’ve installed WebORB for .NET and what version you have installed.
To verify that the service is exposed properly, I can then launch WebORB for .NET’s management console, 
…click in its SERVICES tab, 
…click on .NET Assemblies, and click through to the method getHelloString(), which is exposed by WebORB for .NET as a service.

Note that the console’s Test Drive tab is selected, exposing (among other things) a button labelled “Invoke”. In the list control at the left of the screen, select the getHelloString() method. Then, click on the “Invoke” button to invoke getHelloString(). 
As you can see, the “Name,” “Type,” and “Value” columns’ first row contain, respectively,
- “Result” (the name of getHelloString()’s result),
- “String” (the type of getHelloString()’s result), and
- “Hello, World!” (the value of getHelloString()’s result).
This simple test verifies that:
- getHelloString() is deployed where WebORB for .NET can find it, and
- getHelloString() is returning the value I intended (that is, “Hello, World!”).
…which is a good “reality check” before starting to work on the client-side code.
Now, in the DEPLOYED ASSEMBLIES area on the upper-left corner of the console, go up one level to select HelloWorldService.
This automatically selects the console’s “Generate Code” tab, which, IMHO, is one of the coolest features of WebORB, because it can save an incredible amount of time writing, testing, and debugging code.
It’s not just that WebORB generates code for you; it’s not just that generating code saves you time; and it’s not just that time is money, so that using generated code saves you money — although all of that is true, and important. Even more important, however, is that the generated code encapsulates years of experience in client/server software development. Every time The Midnight Coders’ resident geniuses figure out how to handle another kind of bug, that handling goes into the code generator, so that you don’t have to deal with it yourself.
I’m not saying that WebORB generates perfect code; not at all. Indeed, this blarticle will expose a significant imperfection in WebORB’s code generation….but not quite yet.
Look at the right-hand side of the console. It should look like the image at right.
Note that, of the set of “Code format/style” radio buttons, the one for “Flex Remoting/AS3″ is selected, indicating that Flex-compatible code will be generated. Try selecting other radio buttons. The generated code, shown in the middle of the console, changes to reflect the “Code format/style” radio button currently selected, changes as you select different radio buttons.
Below the stack of radio buttons is another UI section, entitled “Generated code structure:”. It lists the folder(s) and files(s) that can be generated. Select one file, and you’ll see its code appear in the console’s central box. Select a different file, and its code will appear in that box instead.
Now, you could just copy the generated code out of that box and then paste it into your own project. That would be pretty cool. In this blarticle, however, we’re going to do something even cooler.
First, make sure that the “Flex Remoting/AS3″ radio button is selected. Next, look right below the stack of radio buttons. See the checkbox labelled “Generate project files”? Click on it, so that it is checked. Now, press the “Download Code” button.
Windows will throw up a “File Download” dialog, asking you to select the location at which to save the file “weborb.codegen.zip”. Save it wherever is convenient (once you unzip it, you can throw it away, so it doesn’t much matter where you save it).

Now comes the fun part. Open up Flex Builder 4, and in the “File” menu, choose “Import…”. That will bring up the Import screen shown at left.
Find the entry named “Flash Builder”, as highlighted at left. Click on the little ‘+’-sign to its left to reveal more choices.
Select “Flash Builder Project”, as highlighted at right.
Press the “Next” button and you’ll be taken to the “Import Flash Builder Project” screen, shown below.
Wow, these images are really overwhelming this blarticle. I like to use lots of graphics, though, because I find it hard to follow other people’s instructions if they leave steps out, or don’t make them brain-dead simple to follow (which tells you more about my brain than about their instructions, I fear).

In the “Import Flash Builder Project” screen above, click on the upper “Browse…” button at right. That will bring up the standard “Open” directory browser. Use it to navigate to the “weborb.codegen.zip” file you downloaded a couple of steps ago. Select it; press the “Open” button; and you’ll be taken back to the “Import Flash Builder Project” screen above…but this time, the “Finish” button is enabled. Click “Finish”.
That will bring you to yet another screen, this one entitled “Choose Flex SDK Version”. All of my sample apps will use Flex SDK 4 unless otherwise noted (until a future major upgrade is released, anyway) — so be sure that you choose Flex SDK 4 in this screen, too. Click the screen’s “OK” button.
Yet another screen appears — this one entitled “Project Will Be Upgraded,” informing me that “Project HelloWorldService was created with a previous version of Flash Builder. If you save it, you will no longer be able to open this project with older versions of Flash Builder. Continue?” It offers two choices, “OK” and “Cancel”. Click “OK”. That ends the importation of the generated project.
The generated project is shown in Flex Builder’s “Package Explorer” window, as shown at left.
(The project HelloWorldClient1, above it, is local to my machine; you won’t see it on yours.)
As you can see, WebORB’s generated source files — HellowWorldService.as and HelloWorldServiceModel.as — are in the HelloWorldServer package, which is as it should be.
However, I’m not super-happy with the name of the generated project. It’s “HelloWorldService”, but this Flex app is the client-side app. I’d rather name it HelloWorldClient. So I’ll select it, right-click it, and choose “Rename…” from the resulting pop-up menu, renaming it to “HelloWorldClient”. Much better.
Let’s look at HelloWorldClient’s main.mxml, generated by WebORB:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="onLoad()">
<mx:Script>
<![CDATA[
public function onLoad():void
{
}
]]>
</mx:Script>
</mx:Application>
This code was generated for Flex SDK 3.5, but I’m using Flex SDK 4.0. At present, WebORB for .NET does not have the capability of generating code for Flex SDK 4.That’s on the “to-do” list, and should be supported Real Soon Now. Bummer. (See? I told you that WebORB generated less-than-perfect code. We are but mortal.)
No worries, though — the changes are simple enough to make. Here’s the revised code:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="onLoad()">
<fx:Script>
<![CDATA[
public function onLoad():void
{
}
]]>
</fx:Script>
</s:Application>
The changes I made were:
- defining the fx and s namespaces
- re-defining the mx namespace
- changing the Application tags from mx to s
- changing the Script tags from mx to fx
- removing the “layout=absolute” phrase from the Application’s declaration
- changing the indentation in the Application’s declaration to make it easier to read
What is the next step? The source code in HelloWorldService.as, generated by WebORB for .NET, provides a clue. Its header comment says:
/***********************************************************************
The generated code provides a simple mechanism for invoking methods
on the HelloWorldServer.HelloWorldService class using WebORB.
You can add the code to your Flex Builder project and use the
class as shown below:
import HelloWorldServer.HelloWorldService;
import HelloWorldServer.HelloWorldServiceModel;
[Bindable]
var model:HelloWorldServiceModel = new HelloWorldServiceModel();
var serviceProxy:HelloWorldService = new HelloWorldService( model );
// make sure to substitute foo() with a method from the class
serviceProxy.foo();
Notice the model variable is shown in the example above as Bindable.
You can bind your UI components to the fields in the model object.
************************************************************************/
OK, let’s do that! Fleshing out the CDATA block as described above gives us the following:
<fx:Script>
<![CDATA[
import HelloWorldServer.HelloWorldService;
import HelloWorldServer.HelloWorldServiceModel;
[Bindable]
private var model:HelloWorldServiceModel
= new HelloWorldServiceModel();
private var serviceProxy:HelloWorldService
= new HelloWorldService( model );
public function onLoad():void
{
serviceProxy.getHelloString();
}
]]>
</fx:Script>
Cool! Let’s run it! …and absolutely nothing is visible on screen. Doh! I kinda forgot to add a UI.
Let’s add a couple of labels below the Script block:
<s:Label id="helloLabel"
horizontalCenter="0" verticalCenter="0"
text="{model.getHelloStringResult}" />
<s:Label y="34" horizontalCenter="0" text="Result is..."/>
The only interesting bit here is the binding of helloLabel’s text field to model.getHelloStringResult, as suggested by the comment in HelloWorldService.as. When did this property get set? Let’s look at the whole main.mxml file:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="282" height="150"
initialize="onLoad()">
<fx:Script>
<![CDATA[
import HelloWorldServer.HelloWorldService;
import HelloWorldServer.HelloWorldServiceModel;
[Bindable]
private var model:HelloWorldServiceModel
= new HelloWorldServiceModel();
private var serviceProxy:HelloWorldService
= new HelloWorldService( model );
public function onLoad():void
{
serviceProxy.getHelloString();
}
]]>
</fx:Script>
<s:Label id="helloLabel"
horizontalCenter="0" verticalCenter="0"
text="{model.getHelloStringResult}" />
<s:Label y="34" horizontalCenter="0" text="Result is..."/>
</s:Application>
- On line 06, we ensure that onLoad() gets called when the application is initialized.
- On line 21, onLoad() calls serviceProxy.getHelloString().
- On line 16, serviceProxy is declared to be of class HelloWorldService.
…so let’s take a look at HelloWorldService.as.
public function getHelloString( responder:IResponder = null ):void
{
var asyncToken:AsyncToken = remoteObject.getHelloString();
if( responder != null )
asyncToken.addResponder( responder );
}
public virtual function getHelloStringHandler(event:ResultEvent):void
{
var returnValue:String = event.result as String;
model.getHelloStringResult = returnValue;
}
The flow of control is:
- onLoad() calls serviceProxy.getHelloString();
- serviceProxy.getHelloString() calls remoteObject.getHelloString();
- WebORB calls the C# service we defined earlier;
- If the magic is successful, then the C# service’s return value is stuffed into the “result” field of a ResultEvent;
- getHelloStringHandler() is called asynchronously with that ResultEvent object as a parameter;
- model’s getHelloStringResult property is set to event.result (that is, to “Hello, World!”);
- and, finally, because helloLabel’s text field is bound to model.getHelloStringResult,
- helloLabel’s text field is updated to match model.getHelloStringResult, which, deep in the bowels of Flex
- forces helloLabel to be redrawn with its new contents: “Hello, World!”
Now, I would not claim that this is the simplest “Hello, World!” application ever written — far from it. It include four source code files: one on the server, and three on the client. Together, these files contain something like 170 lines of code. That’s not counting WebORB for .NET’s code, or Flex’s code. All together, we’re talking quite a bit of code.
But the thing is, I wrote hardly any of it. A few lines on the server, a few lines on the client, and — presto-chango! — I’ve got a (trivial) client-server application up and running.
I left programming for nearly a decade in the late 1990’s, in part because COM and — shudder! — DCOM made programming so complicated. I did not want to spend my hours tracking down reference counting errors, for example, or bugs in a class’ marshalling/unmarshalling. Blech. That simply wasn’t fun. I got into programming because people paid me to have fun doing it, which is a pretty awesome way to make a living…until it got so complicated that it wasn’t fun anymore.
Now, with .NET, Flex, and WebORB, programming has become fun again — so I’m delighted to get back into coding. Still, I’ve missed a lot, so if you see me making a coding mistake, or a design error, a pattern violation, a smell fault, or somesuch, please don’t hesitate to let me know. By helping me, you’ll be helping lots of other people, too; we can all learn together. You can reach me at jim [att] themidnightcoders [dott] com.
P.S.: Before you ask…Why haven’t I included a link to this sample application’s HelloWorldService.as and HelloWorldServiceModel.as files? Because they are both generated by WebORB. You can generate them for yourself, using WebORB’s management console, as described above. That’s kinda the whole point of this blarticle.