Search code examples
c#.netweb-serviceswcfself-hosting

Running wcf service without App.config doesn't work


I create simple wcf host in console application. It doesn't work and the exception make NO SENSE:/ The exception looks really wierd:

"ContractDescription 'IFooService' has zero operations; a contract must have at least one operation."

because, here is the code and i I have an operation:

[ServiceContract]
public interface IFooService
{
    [OperationContract]
    void DoNothing();

    [OperationContract]
    int GetFoo(int i);
}

public class FooService : IFooService
{
    public void DoNothing()
    {
    }

    public int GetFoo(int i)
    {
        return i + 1;
    }
}

class Program
{
    static void Main(string[] args)
    {
        try
        {
            string address = "http://localhost:9003/FooService";
            Uri addressBase = new Uri(address);

            var svcHost = new ServiceHost(typeof(FooService), addressBase);

            BasicHttpBinding bHttp = new BasicHttpBinding();

            Type contractType = typeof(IFooService);
            ContractDescription contractDescription = new ContractDescription(contractType.Name);
            contractDescription.ProtectionLevel = ProtectionLevel.None;
            contractDescription.ContractType = contractType;
            contractDescription.ConfigurationName = contractType.FullName;
            contractDescription.SessionMode = SessionMode.NotAllowed;

            svcHost.AddServiceEndpoint(new ServiceEndpoint(contractDescription, bHttp, new EndpointAddress(address)));

            svcHost.Open();
            Console.WriteLine("\n\nService is Running as >> " + address);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        Console.ReadKey();
    }
}

This is basically entire code. App.config is left untouched:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
</configuration>

EDIT: A little clue, this way it works: I didn't change service or contract, but moved configuration to App.config, so changed only Main method:

App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <system.serviceModel>
    <services>
      <service name="WcfDemos.ConsoleHost.FooService">
        <endpoint address="http://localhost:9003/FooService" binding="basicHttpBinding"
                  contract="WcfDemos.ConsoleHost.IFooService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

Main:

    static void Main(string[] args)
    {
        try
        {
            string address = "http://localhost:9003/FooService";
            Uri addressBase = new Uri(address);

            var svcHost = new ServiceHost(typeof(FooService), addressBase);
            svcHost.Open();

            Console.WriteLine("\n\nService is Running as >> " + address);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        Console.ReadKey();
    }

Solution

  • Why do you need to use the ContractDescription? I suppose it looks for the settings in the configuration file. You may do the following (use the AddServiceEndpoint method without ContractDescription):

        static void Main(string[] args)
        {
            try
            {
                string address = "http://localhost:9003/FooService";
                Uri addressBase = new Uri(address);
    
                var svcHost = new ServiceHost(typeof(FooService), addressBase);
    
                 BasicHttpBinding bHttp = new BasicHttpBinding();
    
                //Type contractType = typeof(IFooService);
                //ContractDescription contractDescription = new ContractDescription(contractType.Name);
                //contractDescription.ProtectionLevel = ProtectionLevel.None;
                //contractDescription.ContractType = contractType;
                //contractDescription.ConfigurationName = contractType.FullName;
                //contractDescription.SessionMode = SessionMode.NotAllowed;
                //svcHost.AddServiceEndpoint(new ServiceEndpoint(contractDescription, bHttp, new EndpointAddress(address)));
    
                svcHost.AddServiceEndpoint(typeof(IFooService).ToString(), bHttp, address);
    
                svcHost.Open();
                Console.WriteLine("\n\nService is Running as >> " + address);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadKey();
        }
    

    BTW here you may find some library for configuring your WCF services without app.config files: WCF NetTcpBinding Bootcamp