Search code examples
c#wcfweb-configmetadatawcf-binding

"Unable to Download Metadata" when using Two Bindings


In my book, it wants me to expose two endpoints using two bindings: WsHttpBinding & NetTCPBinding and host the service in a host application.

I use the following code in C# to try to connect to my service:

Uri BaseAddress = new Uri("http://localhost:5640/SService.svc");

Host = new ServiceHost(typeof(SServiceClient), BaseAddress);
ServiceMetadataBehavior Behaviour = new ServiceMetadataBehavior();
Behaviour.HttpGetEnabled = true;
Behaviour.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
Host.Description.Behaviors.Add(Behaviour);
Host.Open();

On the service side I have:

[ServiceContract]
public interface IService...

public class SService : IService....

Then in my Config file I have:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>

    <behaviors>
      <serviceBehaviors>
        <behavior name="Behavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <service behaviorConfiguration="WsHttpBehaviour" name="SService.SService">

        <endpoint
          address=""
          binding="wsHttpBinding"
          bindingConfiguration="WsHttpBindingConfig"
          contract="SService.IService" />

        <endpoint
          address=""
          binding="netTcpBinding"
          bindingConfiguration="NetTCPBindingConfig"
          contract="SService.IService" />

        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:5640/SService.svc" />
            <add baseAddress="net.tcp://localhost:5641/SService.svc" />
          </baseAddresses>
        </host>

      </service>
    </services>

  </system.serviceModel>
</configuration>

But when I try to add service reference to my host application, it says unable to download metadata from the address. I don't understand what is wrong and the teacher never taught this.. I decided to go ahead and look it up and learn ahead of time. I used the Editor to create the WebConfig shown above.

Can anyone point me in the right direction? I added Metadata behaviour through the editor and I set the HttpGetEnabled to true.


Solution

  • I can find a few issues with your code that can cause this issue:

    Host = new ServiceHost(typeof(SServiceClient), BaseAddress). Pass here typeof(SService.SService) instead of typeof(SServiceClient). Change like this:

    Host = new ServiceHost(typeof(SService.SService))
    

    <service behaviorConfiguration="WsHttpBehaviour". I guess this should be "Behavior" as you have defined that. Since you have metadata enabled in config, you may remove the lines of code which add a ServiceMetadataBehavior to your servicehost.

    Here is a sample that you can use for reference:

    <system.serviceModel>
        <services>
          <service name="ConsoleApplication1.Service">
            <endpoint address="" binding="wsHttpBinding" contract="ConsoleApplication1.IService" />
            <endpoint address="" binding="netTcpBinding" contract="ConsoleApplication1.IService" />
            <host>
              <baseAddresses>
                <add baseAddress="http://<machinename>:5640/SService.svc" />
                <add baseAddress="net.tcp://<machinename>:5641/SService.svc" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceHost host = new ServiceHost(typeof(Service));
                host.Open();
    
                Console.ReadLine();
            }
        }
    
        [ServiceContract]
        public interface IService
        {
            [OperationContract]
            string DoWork();
        }
    
        public class Service : IService
        {
            public string DoWork()
            {
                return "Hello world";
            }
        }
    }
    

    Metadata will be automatically available at the http baseaddress defined in the config.