Dec
5
2010

Azure Development – Getting Started

Here’s a couple of Azure development ‘gotchas’ that may have had you scratching your head. There’s something to be said about code that you had no hand in creating. And that is that it’s a double edge sword. We need it because we don’t want to be re-creating what’s already been done and with the speed at which technology changes we need to be as nimble as possible. So we rely on a lot of these (frameworks, templates, libraries, etc.) but we may also lose a lot of time in trying to understand or figure out what is being done for us. We may also lose a lot of time if we have to modify what’s generated because it does not fit exactly what we need.

Gotcha#1…make sure you run as admin

Create a new project…select new cloud project. In the pop-up dialog select the default ASP.Net WEB Role along with the default name, WebRole1. Build the project and try to run it.

In order to bypass the above you have to run Visual Studio as an administrator. Right click on the Visual Studio application icon and select ‘Run as administrator’. Select the test project and run it. Now you’ll get the default ASP startup page that was generated by the wizard.

In this case the problem was pretty evident with the dialog message. Under other situations, it is not as evident. If you have set up a (SQL Express) database you’ll get a compiler error with a message indicating ‘access denied’ to the mdf file. Again, it means you forgot to start as admin.

Domain Service, just a WCF service endpoint

Although RIA Services and the associated DomainService’s primary focus is as a data access layer, it is essentially a WCF service endpoint. The ‘wizardry’ does help in creating the basic CRUD operations on an existing data model but that’s the icing on the cake. To demonstrate that let’s look at an example. Since I’m primarily interested in the triumvirate of Silverlight-RIA-Azure we’ll bake a sample around that configuration. And since we are simply demonstrating the above statement we won’t have any data models, just a simple method. Add a Silverlight project to the solution created previously.

 

You’ll notice on the prompt dialog that the wizard by default will set it up so that the Silverlight application will be hosted in the existing WebRole. Since we will be using RIA Services we simply need to make the appropriate selection in the checkbox. If you build and run the application as it stands now you’ll see a blank screen instead of the default ASP home page. Nothing to see but at least you have the right pieces hooked up. So now let’s add some code on each side so we can test the communication.

On the WebRole1 project right click to ‘Add New Item’ then select DomainService. As you can see in the prompt dialog below the only thing this will do is create the linkage between the client and the service. If we had a data object model the wizards would be able to pick those up and build some skeletal methods for basic CRUD operations. But what we want to show is that we don’t need any of that and still get the plumbing.

 

If you now build the solution you should see a warning that says that we have a service but we’re not exposing anything on it. And that’s true, we have an empty DomainService class, so far. But it’s interesting to see what the RIA Services code generation facility does for us. The Solution Explorer pane by default does not show auto-generated code files. So first select the Silverlight project and then select the ‘Show All Items’ toolbar item in the Solution Explorer pane. A new folder labeled ‘Generated_Code’ will appear in the list. If you now open the generated code file you’ll see that there is only a WebContext class defined in the file along with a static member. This is what can be used to access the authentication domain service, if there is any authentication implemented.

Let’s modify our domain service by adding a method that simply returns a string as shown below.


[EnableClientAccess()]
public class AzureTest1DomainService : DomainService
{
    [Invoke]
    public string OperatorName()
    {
        return "Harry";
    }
}

The Invoke decorator simply specifies that we’re dealing with non-entity data, just being explicit with the code generator. If we re-build the solution you’ll notice that the warning is gone. Now let’s take a look at the generated code file.

What do we have? If you think about it, what’s generated is a proxy class to a WCF service endpoint that’s hosted by a special WCF ServiceHost for RIA. At least that’s how I see it. So in the generated code file we see a new class named AzureTest1DomainContext. There are a couple of overloaded constructors, asynchronous access methods to our single service method-OperatorName, and interface definition for the domain service. That’s everything we need to be able to access our service from the client.

Now let’s see how we can put that proxy class to use. Add a button and a text block to the client design surface and create an event handler for the button as shown below.


private void buttonGetName_Click(object sender, RoutedEventArgs e)
{
    AzureTest1DomainContext context = new AzureTest1DomainContext();
    context.OperatorName(new Action<InvokeOperation><string>>(OpNameCallback), null);

}

private void OpNameCallback(InvokeOperation args)
{
    textOpName.Text = args.Value;
}

In the handler we simply create an instance of our proxy class and call our method asynchronously. That means of course that we need to provide a callback method, as shown above, through which we will be notified once the call completes. If you build and run the project you’ll be able to verify the complete communication cycle along with the returned data. And we can see the basic functionality provided for us by the RIA Services. We can then easily expand the service to include much richer functionality, full data models, validation, etc.

Gotcha#2…sequence does matter

There is a Silverlight project template that has pre-cooked functionality that we can explore at this point and at the same time point out a couple of…how should I put it, potential distractions. The Silverlight Business Application template provides a lot more ‘starter’ functionality that is typically required for business apps including user authentication. Let’s start by creating, as we did previously, a default Azure app with a basic WebRole. To the WebRole add as we did before a DomainService along with the single method previously described. Now instead of adding a simple Silverlight project template, go ahead and select the Business Application template. Build the solution and run it. You’ll see the default business app interface which provides some basic starter navigation mechanisms.

So now let’s add a button and text block to perform the same operations as we did previously. We’ll just throw them on the Home page for this exercise. When you go to implement the event handler you’ll notice that there is no context help showing up for the DomainContext class. If you look in the generated code file you’ll find the WebContext class, an AuthenticationContext class, and a UserRegistrationContext class but no AzureTestDomainContext (or whatever you called it). The first clue is that when we added the Silverlight Business Application project we did not get a prompt dialog indicating where the application was to be hosted. So, essentially the Silverlight project is not being hosted in the cloud as we would like.

We can proceed two ways, first we can fix the current solution by modifying the projects or we can start from the beginning and follow a different sequence. To fix the current solution the first thing that’s needed is to get the Silverlight app hosted in Azure. Right click on the Roles folder of the Azure project. Several options are available including one that is to add an existing Role already defined in the solution. If you select that option you’ll be presented with the WEB service that was created for the Silverlight Business Application. The default WebRole1 that was in that folder can then be deleted.

Since we had already added the DomainService to the WebRole we need to add it to the new role that was just added to the Azure project. There is already a Services folder that contains the authentication and user registration services so you can just add it there. If you build it you will see that the DomainContext class now appears in the generated code.

The other solution is to follow a different sequence from the beginning. First create the Silverlight Business Application project and THEN follow by adding the Azure project. But when prompted to select a role leave it blank. Build the solution to get things compiled. The Roles folder in the Azure project will be empty so right click on it to add a WebRole. As above you can select the existing WEB service that was created for the Silverlight project. You can now proceed to add a DomainService to the WEB service project.

Next…

I think there is a big convergence of technologies that have been taking place in the past few years. This convergence is making possible a whole range of new business opportunities if only we can identify them. And of course that’s usually the biggest hurdle in new ventures-seeing the opportunities. My main focus is on business applications that optimize typical business processes, specifically human operations. There is a set of operations that are typical of this class of applications and I plan to explore those in the context of Silverlight (desktop and phone), Azure, and RIA Services.