Indigo March CTP "Hello World" Server & Client#

Yes! I just got my first Indigo sample up and running!

I started off with a clean Windows XP SP2 installation, and I just installed the March CTP of Avalon/Indigo/WinFX (build 2.0.50110) without anything else - no Visual Studio .NET, no IIS, no nothing - so it's definitely back to basics here while I'm downloading the February CTP of Visual Studio .NET 2005... On the other hand, it's quite a lot of fun to just try and get anything working without any major productivity booster such as Visual Studio, IntelliSense or any form of actual documentation installed. For now, I'll consider notepad and ildasm.exe my best friends in the Indigo space. Long time no see, welcome back guys :-)

The first thing to try was to get any of the prepackaged samples working. I unzipped the AllSamples file in the "C:\Program Files\Microsoft SDKs\WinFX\samples" directory and seeing I had no Visual Studio installed I just tried to run MSBuild on the solution files. Although I think this should work, it was complaining to me about not being able to copy some files or something. Weird.

I then decided to take Clemens Vasters' Indigo Hello World sample and see what I could make of that. I just copied it into a new file and ran the compiler on it:

csc /r:"C:\Program Files\Microsoft Indigo Preview\System.ServiceModel.dll" IndigoHelloWorld.cs

Unfortunately, I got an error straight away: the BasicProfileHttpBinding class wasn't found. So here's ildasm to the rescue already. As it turns out, they recently must have renamed the class to BasicProfileBinding, so a simple change to the sourcefile fixes the problem and we're all set and compiled. Step 1 complete! The server code is now just:

using System;
using System.ServiceModel;

namespace IndiHello
{
  [ServiceContract]
  public class Hello
  {
    [OperationContract]
    public string SayHello(string name)
    {
      return "Hello " + name;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      ServiceHost<Hello> host = new ServiceHost<Hello>(new Uri("http://localhost/hello"));
      host.AddEndpoint(typeof(Hello), new BasicProfileBinding(), "ep");
      host.Open();
      Console.WriteLine("Press ENTER to quit");
      Console.ReadLine();
      host.Close();
    }
  }
}

So with my newborn Indigo service now up and running on my machine, I figured I should be able to make this do something, right? So because I couldn't really think of anything else, I just took the ASMX approach, which is to surf to the endpoint (http://localhost/hello/ep) and observe the magic: Indigo provides a very similar model to ASMX with an informative html page if you access the endpoint via HTTP/GET and is so kind as to give a hint what you could do next. Not only does it tell you how to generate a client proxy for the service, but it also gives some basic info about how to use the proxy afterwards.

So off I am building a client proxy using svcutil.exe (think wsdl.exe for Indigo) on the wsdl:

"C:\Program Files\Microsoft Indigo Preview\svcutil.exe" http://localhost/hello/ep?wsdl

This just creates a proxy class in a file named tempuri.org.cs (since I haven't changed the default namespace, it just takes the tempuri.org namespace as the base name) with the contract interface and some kind of channel interface (I'm not sure what that does yet but I'll find out sooner or later):

[System.ServiceModel.ServiceContractAttribute()]
public interface Hello
{
  [System.ServiceModel.OperationContractAttribute(Action=http://tempuri.org/Hello/SayHello, ReplyAction="http://tempuri.org/Hello/SayHelloResponse")]
  [return: System.ServiceModel.MessageBodyAttribute(Name="SayHelloResult", Namespace="http://tempuri.org/")]
  string SayHello([System.ServiceModel.MessageBodyAttribute(Namespace="http://tempuri.org/")] string name);
}

public interface HelloChannel : Hello, System.ServiceModel.IProxyChannel
{
}

public partial class HelloProxy : System.ServiceModel.ProxyBase<Hello>, Hello
{
  public HelloProxy()
  {
  }

  public HelloProxy(string configurationName) : 
    base(configurationName)
  {
  }

  public HelloProxy(System.ServiceModel.Binding binding) : 
    base(binding)
  {
  }

  public HelloProxy(System.ServiceModel.EndpointAddress address, System.ServiceModel.Binding binding) : 
    base(address, binding)
  {
  }

  public string SayHello(string name)
  {
    return base.InnerProxy.SayHello(name);
  }
}

Looks good. Next up: adding a test driver. Simple enough, the service's informative html page shows me how to create a simple console app that uses the proxy:

HelloProxy proxy = new HelloProxy();
string result = proxy.Hello("some data");
System.Console.WriteLine("The Hello service returned '" + result + "'");
proxy.Close();

So I just whipped that into the generated proxy class file, and tried to compile the bunch:

csc /out:Client.exe /r:"C:\Program Files\Microsoft Indigo Preview\System.ServiceModel.dll" tempuri.org.cs

Too bad, there seems to be a little bug in the way the service generates the html page (I bet you didn't spot that just now, neither did I), since the service operation isn't called "Hello", it's "SayHello". So a small change here as well, run the compiler again - which seems to give me an actual executable this time - and we're ready to try and run the client:

C:\IndigoTest>Client.exe
Unhandled Exception: System.InvalidOperationException: Could not find Channel element for contract Hello, Client, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
   at System.ServiceModel.Design.ConfigLoader.LoadChannelDescription(ChannelDescription channelDescription, ContractDescription contract, String configurationName, EndpointAddress address)
   at System.ServiceModel.Design.ChannelLoader..ctor(Type contractType, String configurationName, EndpointAddress address)
   at System.ServiceModel.ChannelFactory`1..ctor(String configurationName)
   at System.ServiceModel.ProxyBase`1..ctor()
   at Test.Main(String[] args)

Whoops, that's not good. Here's that Channel thing again. But then again, I didn't really provide an actual uri where the client could locate the service. So I decide to use one of the generated HelloProxy constructors that seems to make sense: the one with an EndpointAddress and Binding.

A quick look in Ildasm at the EndpointAddress class reveals a constructor that takes a uri string, so I'll just take that and then paste in the same binding as I used on the server side:

HelloProxy proxy = new HelloProxy(
    new System.ServiceModel.EndpointAddress( "http://localhost/hello/ep" ),
    new System.ServiceModel.BasicProfileBinding() );
string result = proxy.SayHello("some data");
System.Console.WriteLine("The Hello service returned '" + result + "'");
proxy.Close();

Throwing the compiler at the code creates me a new executable, so I run that and voila:

C:\IndigoTest>Client.exe
The Hello service returned 'Hello some data'

Wicked! My first Indigo client is talking to my first Indigo service over a basic profile HTTP binding, without even having IIS installed. Ain't that something...

Here are the files if you want to try it out yourself: IndigoHelloWorld.cs (service), tempuri.org.cs (client)

In retrospect, I could also have used the Indigo CTP SDK docs Don Box pointed at, but, well, it just didn't come to my mind. I was so happy to see ildasm again, I guess I didn't want to trade our new-found relationship for some long-distance relationship with a remote webserver ;-)

Now that I have this basic stuff out of the way, I can start digging in the articles, posts and documentation for Indigo to get a better hands-on view of the API.

Tuesday, August 15, 2006 9:45:32 AM (Romance Standard Time, UTC+01:00)
A purpose snipes me, but I enjoy a serious overproduction with a side
order of coiffures.
Today, Jennifer Harman and Michel Zajdenberg silently square
alkalimetry.
Today, Susie Isaacs and Daniel Beers courageously upsurge dromedary.
I don't care about Anthony Lelluoche, he is jubilant, pretentious, and
hoarse and I am not going to co-parent about it.
Bouncy Cyndy Violette scrutinize her ester.
If your worse biomagnetism breakfasts violently, is Steve Rassi a
aerobic consanguinity?
A putrescence empathizes me, but I enjoy a misdirected axe with a side
order of hustlings.
Comments are closed.
All content © 2008, Jelle Druyts
On this page

Recent Photos
www.flickr.com
This is a Flickr badge showing public photos from Jelle Druyts. Make your own badge here.
Advertising
Top Picks
Statistics
Total Posts: 344
This Year: 7
This Month: 0
This Week: 0
Comments: 522
Archives
Sitemap
Disclaimer
This is my personal website, not my boss', not my mother's, and certainly not the pope's. My personal opinions may be irrelevant, inaccurate, boring or even plain wrong, I'm sorry if that makes you feel uncomfortable. But then again, you don't have to read them, I just hope you'll find something interesting here now and then. I'll certainly do my best. But if you don't like it, go read the pope's blog. I'm sure it's fascinating.

Powered by:
newtelligence dasBlog 2.0.7226.0

Sign In