wcfcastle-windsorwcffacility

Castle WcfFacility Publishing MEX Endpoints


I am writing a simple WCF Service and hosting it within a console application.

I know the service is functioning, because a simple client can perform operations exposed on the service.

If I point the Wcf Test Client to my service, I receive the following error (note tempuri.com was really localhost, but stackoverflow requires me to either wrap this output as a code block or include a FQDN):

System.InvalidOperationException : Metadata contains a reference that cannot be resolved: 'http://tempuri.com:27198/UsingWindsor.svc?wsdl'. ----> System.ServiceModel.ProtocolException : Content Type application/soap+xml; charset=utf-8 was not supported by service http://tempuri.com:27198/UsingWindsor.svc?wsdl. The client and service bindings may be mismatched. ----> System.Net.WebException : The remote server returned an error: (415) Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'..

Not fully understanding the error, I starting playing with the tests that are part of the WcfFacility.

I have modified a test in the Castle.Facilities.WcfIntegration.Tests.ServiceHostFixture to exhibit the same error I am having (of course it works without the modifications):

[Test]
public void CanPubishMEXEndpointsUsingDefaults()
{
    using (new WindsorContainer()
                .AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero)
                .Register(Component.For<Operations>()
                    .DependsOn(new { number = 42 })
                    .AsWcfService(new DefaultServiceModel()
                        .AddBaseAddresses(
                            //"net.tcp://localhost/Operations",
                            "http://localhost:27198/UsingWindsor.svc")
                        .AddEndpoints(
                            WcfEndpoint.ForContract<IOperations>()
                                //.BoundTo(new NetTcpBinding { PortSharingEnabled = true })
                                .BoundTo(new BasicHttpBinding())
                            )
                        .PublishMetadata(mex => mex.EnableHttpGet())
                    )
                ))
            {
                //var tcpMextClient = new MetadataExchangeClient(new EndpointAddress("net.tcp://localhost/Operations/mex"));
                //var tcpMetadata = tcpMextClient.GetMetadata();
                //Assert.IsNotNull(tcpMetadata);

                var httpMextClient = new MetadataExchangeClient(new EndpointAddress("http://localhost:27198/UsingWindsor.svc?wsdl"));
                var httpMetadata = httpMextClient.GetMetadata();
                Assert.IsNotNull(httpMextClient);
            }
        }

Why does this test fail when I eliminate the NetTcp binding and bind to Http? My configuration in my console app is very similar to the modified test. (including for completeness)

container.Register(Component.For<ISimpleService>()
                        .ImplementedBy<SimpleService>()
                        .AsWcfService(new DefaultServiceModel()
                                            .AddBaseAddress("http://localhost:515")
                                            .PublishMetadata(x => x.EnableHttpGet())
                                            .AddEndPoints(WcfEndpoint.ForContract<ISimpleService>().BoundTo(new BasicHttpBinding()).At("SimpleService"))));

Solution

  • Not quite sure why the test is failing, but I did solve my problem.

    I changed the registration from this:

    container.Register(Component.For<ISimpleService>()
                            .ImplementedBy<SimpleService>()
                            .AsWcfService(new DefaultServiceModel()
                                                .AddBaseAddress("http://localhost:515")
                                                .PublishMetadata(x => x.EnableHttpGet())
                                                .AddEndPoints(WcfEndpoint.ForContract<ISimpleService>().BoundTo(new BasicHttpBinding()).At("SimpleService"))));
    

    to this:

    container.Register(Component.For<ISimpleService>()
                            .ImplementedBy<SimpleService>()
                            .AsWcfService(new DefaultServiceModel()
                                                .AddBaseAddress("http://localhost:515/SimpleService")
                                                .PublishMetadata(x => x.EnableHttpGet())
                                                .AddEndPoints(WcfEndpoint.ForContract<ISimpleService>().BoundTo(new BasicHttpBinding()))));
    

    When defining the BaseAddress I now include the "SimpleService" and remove it when defining the EndPoints.