WCF Nightmare

I have been having fun with WCF.  I have been trying to switch off anonymous authentication using WSHttpBinding. Then I found this post.  It explains that WSHttpBinding over HTTP requires anonymous authentication to be enabled.  I had accidentally set this up in an environment that I did make work.

Adding WPF and WCF to VS2005

Microsoft as I have said before are not very good at writing installers.
They have a tendancy to ignore possible futures and always test for exact current versions.

This is the case when you try and add the WPF and WCF addons to VS2005.

Here
is an article on how to make it work once you have installed service pack 1 for .NET 3.0

The idiot who wrote the installer tested for the presense of the uninstall option for the initial version of .NET 3.0, ignoring the possibility of a service pack.

This is not the first time I have seen a microsoft installer perform this stupidity.
Back in the day I learnt a lot about the registry configuration for COM objects the hard way.
The 16 bit version of VB installed a common library.   Subsequently this library had a 32 bit version released too.
If you installed the 16 bit version over the 32 bit one it clobbered the registry sufficiently to break the later version.
Rather inconsiderately the application suite that I was assisting used both versions…
I had to write a patch utility to correct this problem.  COM always had a technique for handling this kind of versioning problem but it was clear that whoever wrote the installer did not understand this.

Pure Boo WCF problem

I have been trying to create a pure WCF service that exposes metadata.
Learning WCF implies that MexHttpBinding exists as a class that can be used like HttpBinding.

Unfortuantely I get HTTP 405 errors!

The following host:

namespace IndigoService

import System
import System.ServiceModel
import System.ServiceModel.Description

host = ServiceHost(typeof(IndigoService.HelloIndigoService), Uri(“http://localhost:8000/HelloIndigo”))

mexBehaviour = ServiceMetadataBehavior()
mexBehaviour.HttpGetEnabled = true
host.Description.Behaviors.Add(mexBehaviour)

host.AddServiceEndpoint(typeof(IndigoService.IHelloIndigoService), BasicHttpBinding(), “HelloIndigoService”);
host.AddServiceEndpoint(typeof(System.ServiceModel.Description.IMetadataExchange), BasicHttpBinding(), “mex”);

host.Open();
print “Press any key to terminate”
Console.ReadKey()

Running the service and calling:

C:devboowcf>svcutil /o:serviceproxy.cs /config:app.config http://localhost:8000/HelloIndigo/mex

Produces the following errors:

Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.30]
Copyright (c) Microsoft Corporation.  All rights reserved.

Attempting to download metadata from ‘http://localhost:8000/HelloIndigo/mex’ usi
ng WS-Metadata Exchange or DISCO.
Microsoft (R) Service Model Metadata Tool
[Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.30]
Copyright (c) Microsoft Corporation.  All rights reserved.

Error: Cannot obtain Metadata from http://localhost:8000/HelloIndigo/mex

If this is a Windows (R) Communication Foundation service to which you have acce
ss, please check that you have enabled metadata publishing at the specified addr
ess.  For help enabling metadata publishing, please refer to the MSDN documentat
ion at http://go.microsoft.com/fwlink/?LinkId=65455.

WS-Metadata Exchange Error
    URI: http://localhost:8000/HelloIndigo/mex

    Metadata contains a reference that cannot be resolved: ‘http://localhost:800
0/HelloIndigo/mex’.

    Content Type application/soap+xml; charset=utf-8 was not supported by servic
e http://localhost:8000/HelloIndigo/mex.  The client and service bindings may be
 mismatched.

    The remote server returned an error: (415) Cannot process the message becaus
e the content type ‘application/soap+xml; charset=utf-8’ was not the expected ty
pe ‘text/xml; charset=utf-8’..

HTTP GET Error
    URI: http://localhost:8000/HelloIndigo/mex

    There was an error downloading ‘http://localhost:8000/HelloIndigo/mex’.

    The request failed with the error message:

<s:Envelope xmlns:s=”http://schemas.xmlsoap.org/soap/envelope/”><s:Body><s:Fault
><faultcode xmlns:a=”http://schemas.microsoft.com/ws/2005/05/addressing/none”>a:
ActionNotSupported</faultcode><faultstring xml:lang=”en-GB”>The message with Act
ion ” cannot be processed at the receiver, due to a ContractFilter mismatch at
the EndpointDispatcher. This may be because of either a contract mismatch (misma
tched Actions between sender and receiver) or a binding/security mismatch betwee
n the sender and the receiver.  Check that sender and receiver have the same con
tract and the same binding (including security requirements, e.g. Message, Trans
port, None).</faultstring></s:Fault></s:Body></s:Envelope>
–.

If you would like more help, type “svcutil /?”

It appears that mex must be enabled in a config file – you can’t do it in code!

wcf demo in Boo

This is the promised simple wcf demo in boo.

It is based upon the examples in Learning WCF by Michelle Leroux Bustemante.

### Contract.boo ###
namespace IndigoService

import System.ServiceModel

[ServiceContract(Namespace:”http://foo/bar&#8221;)]
interface IHelloIndigoService:
    [OperationContract]
    def SayHello() as string:
        pass

### Service.boo ###
namespace IndigoService

#import System.ServiceModel
   
class HelloIndigoService(IHelloIndigoService):
    def SayHello() as string:
        return “Hello Indigo”

### Host.boo ###
namespace IndigoService

import System.ServiceModel
import System

host = ServiceHost(typeof(IndigoService.HelloIndigoService), Uri(“http://localhost:8000/HelloIndigo&#8221;))
host.AddServiceEndpoint(typeof(IndigoService.IHelloIndigoService), BasicHttpBinding(), “HelloIndigoService”);
host.Open();
print “Press any key to terminate”
Console.ReadKey()

### Client.boo ###
namespace IndigoService

import System
import System.ServiceModel

try:
    ep = EndpointAddress(“http://localhost:8000/HelloIndigo/HelloIndigoService&#8221;)
    proxy as IHelloIndigoService
    proxy = (ChannelFactory [of IHelloIndigoService]).CreateChannel(BasicHttpBinding(),ep)
    Console.WriteLine(proxy.SayHello())
    Console.ReadKey()
except e:
    print “Problem with server – probably not there”
    # print e

### default.build ###
<?xml version=”1.0″ ?>

<project name=”wcfdemo” default=”build”>
<property name=”boo.dir” value=”C:/boo/bin” />
    <target name=”build” depends=”wcfserver,wcfclient” />
    <target name=”wcfserver”>
        <loadtasks assembly=”${boo.dir}/Boo.NAnt.Tasks.dll” />
                 <booc output=”wcfserver.exe” target=”exe”>
            <references>
                <include name=”C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/*.dll” />
            </references>
            <sources>
                <include name=”Service.boo” />
                <include name=”Host.boo” />
                <include name=”Contract.boo” />               
            </sources>
        </booc>
    </target>
    <target name=”wcfclient”>
        <loadtasks assembly=”${boo.dir}/Boo.NAnt.Tasks.dll” />
                 <booc output=”wcfclient.exe” target=”exe”>
            <references>
                <include name=”C:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0/*.dll” />
            </references>
            <sources>
                <include name=”Client.boo” />
                <include name=”Contract.boo” />               
            </sources>
        </booc>
    </target>
</project>