Cook Computing

 

September 01, 2007

Contract Name Not Found In List Of Contracts

I have just started to dive into Windows Communication Foundation. Long overdue I know. One beginner's tip is that if an instance of InvalidOperationException is thrown when you try to create your service host and the exception's message is something like this:

The contract name 'TestContract' could not be found in the list of contracts implemented by the service 'TestService'.

... it may be because you have forgotten to specify that the interface is a service contract. You need to decorate the interface with the ServiceContract attribute:

[ServiceContract]
public interface TestContract
{
  [OperationContract]
  int Add(int x, int y);
}
Posted by at 05:33 PM. Permalink.

January 18, 2007

XML-RPC Server Using HttpListener

I've had a handful of requests from people who want to use the .Net System.Net.HttpListener class as the basis for an XML-RPC server implemented using XML-RPC.NET.

Acquiring the request synchronously via the HttpListener GetContext method, the top level code could look like this:

using System;
using System.IO;
using System.Net;
using CookComputing.XmlRpc;

class _
{
  public static void Main(string[] prefixes)
  {
    HttpListener listener = new HttpListener();
    listener.Prefixes.Add("http://127.0.0.1:11000/");
    listener.Start();
    while (true)
    {
      HttpListenerContext context = listener.GetContext();
      ListenerService svc = new StateNameService();
      svc.ProcessRequest(context);
    }
  }
}

ListenerService is an abstract base class we will define below and StateNameService is the derived class which contains the implementation of the methods required in the XML-RPC service:

public class StateNameService : ListenerService
{
  [XmlRpcMethod("examples.getStateName")]
  public string GetStateName(int stateNumber)
  {
    if (stateNumber < 1 || stateNumber > m_stateNames.Length)
      throw new XmlRpcFaultException(1, "Invalid state number");
    return m_stateNames[stateNumber - 1];
  }

  string[] m_stateNames
    = { "Alabama", "Alaska", "Arizona", "Arkansas",
        "California", "Colorado", "Connecticut", "Delaware", "Florida",
        "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", 
        "Kansas", "Kentucky", "Lousiana", "Maine", "Maryland", "Massachusetts",
        "Michigan", "Minnesota", "Mississipi", "Missouri", "Montana",
        "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", 
        "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma",
        "Oregon", "Pennsylviania", "Rhose Island", "South Carolina", 
        "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", 
        "Washington", "West Virginia", "Wisconsin", "Wyoming" };
}

The ListenerService class derives from the XmlRpcHttpServerProtocol class and so is similar in this respect to the XmlRpcService class which is used as the bass class for XML-RPC services which are hosted in ASP.NET.

public abstract class ListenerService : XmlRpcHttpServerProtocol
{
  public virtual void ProcessRequest(HttpListenerContext RequestContext)
  {
    try
    {
      IHttpRequest req = new ListenerRequest(RequestContext.Request);
      IHttpResponse resp = new ListenerResponse(RequestContext.Response);
      HandleHttpRequest(req, resp);
      RequestContext.Response.OutputStream.Close();
    }
    catch (Exception ex)
    {
      // "Internal server error"
      RequestContext.Response.StatusCode = 500;  
      RequestContext.Response.StatusDescription = ex.Message;
    }
  }
}

The remaining code defines the ListenerRequest and ListenerResponse classes. These essentially allow us to access the .Net HttpListenerRequest and HttpListenerResponse classes via the XML-RPC.NET IHttpRequest and IHttpResponse interfaces:

public class ListenerRequest : CookComputing.XmlRpc.IHttpRequest
{
  public ListenerRequest(HttpListenerRequest request)
  {
    this.request = request;
  }

  public Stream InputStream 
  { 
    get { return request.InputStream; } 
  }

  public string HttpMethod 
  { 
    get { return request.HttpMethod; } 
  }

  private HttpListenerRequest request;
}

public class ListenerResponse : CookComputing.XmlRpc.IHttpResponse
{
  public ListenerResponse(HttpListenerResponse response)
  {
    this.response = response;
  }

  string IHttpResponse.ContentType
  {
    get { return response.ContentType; }
    set { response.ContentType = value; }
  }

  TextWriter IHttpResponse.Output 
  {
    get { return new StreamWriter(response.OutputStream); } 
  }

  Stream IHttpResponse.OutputStream 
  {
    get { return response.OutputStream; } 
  }

  int IHttpResponse.StatusCode
  {
    get { return response.StatusCode; }
    set { response.StatusCode = value; }
  }

  string IHttpResponse.StatusDescription
  {
    get { return response.StatusDescription; }
    set { response.StatusDescription = value; }
  }

  private HttpListenerResponse response;
}

This sample server can then be accessed by a client implemented in the usual way:

using System;
using System.Collections.Generic;
using System.Text;
using CookComputing.XmlRpc;

[XmlRpcUrl("http://127.0.0.1:11000/index/")]
public interface IStateName : IXmlRpcProxy
{
  [XmlRpcMethod("examples.getStateName")]
  string GetStateName(int stateNumber);

}

class Program
{
  static void Main(string[] args)
  {
    IStateName proxy = XmlRpcProxyGen.Create<IStateName>();
      string ret = proxy.GetStateName(1);
  }
}

I'll illustrate how to use the asynchronous HttpListener methods BeginGetContext and EndGetContext in a future post. I'll also add the ListenerService, ListenerRequest, and ListenerResponse classes to the next release of XML-RPC.NET.

Posted by at 01:34 PM. Permalink.

January 11, 2007

Object of Desire

The iPhone ????.

Apple's Mobile Phone at MacWorld EXPO, Moscone Center, San Francisco.

© David Pham

Posted by at 11:52 AM. Permalink.

January 04, 2007

Functional Style Regex Engine in C#

Wesner Moise's recent post Hard Problems, Simple Solutions speculates about implementing regular expression matching using a functional style. He points to a regular expression engine in 14 lines of Python and suggests this could be ported to C# using iterators and anonymous functions.

Wesner writes that the regular expression would be composed functionally through a string:

re = Sequence( term1, Plus( term2, Alternate( term3, term4 )), term 5)

and the results would be returned as a collection by applying the regular expression to the list to be searched:

results = re( list_to_search )

I thought I would attempt a port of the Python code to learn a bit more about iterators and anonymous functions and came up with the class Rgx below (non-generic for strings only to make the code easier to read). This allows the sample from the Python code to be written like this:

// c(a|d)+r

Rgx.Expr e = 
  Rgx.Seq(Rgx.Char('c'), 
    Rgx.Seq(Rgx.Plus(Rgx.Alt(Rgx.Char('a'), Rgx.Char('d'))), 
      Rgx.Char('r')));

foreach (string r in e("cdar"))
  Console.WriteLine("Match with remainder: {0}", r);

The lack of global functions in C# makes the code uglier Wesner's suggested code above (btw why no global functions in C#? I believe the CLR supports them) and because the yield statement cannot be used inside anonymous method blocks it is necessary create the separate iterators SeqIterator and CharIterator. Note that like the Python code this class doesn't do anything useful; think of it as a proof of concept.

     
class Rgx
{
  public delegate IEnumerable Expr(string s);

  static IEnumerable IconCat(IEnumerable xs, IEnumerable ys)
  {
    foreach (string x in xs) yield return x;
    foreach (string y in ys) yield return y;
  }

  static public IEnumerable Nil(string s)
  {
    yield return s;
  }

  static public Expr Seq(Expr l, Expr r)
  {
    return delegate(string s)
    {
      return SeqIterator(s, l, r);
    };
  }

  static IEnumerable SeqIterator(string s, Expr l, Expr r)
  {
    foreach (string sl in l(s))
      foreach (string sr in r(sl))
        yield return sr;
  }

  static public Expr Alt(Expr l, Expr r)
  {
    return delegate(string s)
    {
      return IconCat(l(s), r(s));
    };
  }

  static public Expr Star(Expr e)
  {
    return delegate(string s)
    {
      return IconCat(Nil(s), Seq(e, Star(e))(s));
    };
  }

  static public Expr Plus(Expr e)
  {
    return Seq(e, Star(e));
  }

  static public Expr Char(char c)
  {
    return delegate(string s)
    {
      return CharIterator(s, c);
    };
  }

  static IEnumerable CharIterator(string s, char c)
  {
    if (s.Length > 0 && s[0] == c)
    {
      yield return (s.Substring(1));
    }
  }
}
Posted by at 12:37 PM. Permalink.

November 03, 2006

DeveloperDeveloperDeveloper 4

I've registered for DeveloperDeveloperDeveloper 4 on Saturday 2nd December. I missed DDD3 because I was on vacation but I found the first two were well worth attending.

From the DDD site:

This FREE one day event builds on the success of the previous DeveloperDeveloperDeveloper Days. As before it is all about developers learning, sharing and interacting with each other in an informal and relaxed atmosphere.

There will be NO Microsoft speakers presenting, just speakers from the UK .NET developer community; although we will have some of the Microsoft UK Developer Team on hand to help out and chat to attendees.

The day is put together by the community for the community, in other words you. With Microsoft UK very kindly providing the venue, logistic support and a free lunch.

Register here but be quick.

Posted by at 07:56 AM. Permalink.