Wcf – Hosting a Simple Wcf Service in Console

consolewcf

I am trying to create a simple ConsoleApplication in which i would like to host a simple wcf service.

Here is the code for my

namespace HostConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (System.ServiceModel.ServiceHost host = new System.ServiceModel.ServiceHost(typeof(FirstWcfService.Service)))
            {
                host.Open();
                Console.WriteLine("Sai");
                Console.ReadLine();
            }
        }
    }
}

Then i have added an app.config which looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="FirstWcfService.Service" behaviorConfiguration="ServiceBehavior">
                <endpoint address="FirstWcfService" binding="netTcpBinding" contract="FirstWcfService.IService"/>
                <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:9101/"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ServiceBehavior" >
                    <serviceMetadata httpGetEnabled="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

When i run the host console app i get this exception:

System.InvalidOperationException was
unhandled Message="Could not find a
base address that matches scheme http
for the endpoint with binding
MetadataExchangeHttpBinding.
Registered base address schemes are
[net.tcp]."
Source="System.ServiceModel"
StackTrace:
at System.ServiceModel.ServiceHostBase.MakeAbsoluteUri(Uri
relativeOrAbsoluteUri, Binding
binding, UriSchemeKeyedCollection
baseAddresses)
at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase
host, ServiceDescription description,
ServiceElement serviceElement,
Action`1 addBaseAddress)
at System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader
configLoader, ServiceDescription
description, ServiceElement
serviceSection)
at System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader
configLoader, ServiceDescription
description, String configurationName)
at System.ServiceModel.ServiceHostBase.ApplyConfiguration()
at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection
baseAddresses)
at System.ServiceModel.ServiceHost.InitializeDescription(Type
serviceType, UriSchemeKeyedCollection
baseAddresses)
at System.ServiceModel.ServiceHost..ctor(Type
serviceType, Uri[] baseAddresses)
at HostConsoleApplication.Program.Main(String[]
args) in C:\Documents and
Settings\navin.pathuru\My
Documents\Visual Studio
2008\Projects\Solution2\HostConsoleApplication\Program.cs:line
13
at System.AppDomain._nExecuteAssembly(Assembly
assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String
assemblyFile, Evidence
assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object
state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback
callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

Just wondering if how to fix this.
Thanks
N

Best Answer

Well, I think the problem is this:

  • you have a base address for net.tcp
  • you have a MEX http endpoint defined (but no http base address)

Basically if you want to use MEX over http, you need to supply either a full address for the MEX endpoint, or a http base address (if you only specify a relative address).

Solution 1: specify a full address for the MEX endpoint:

 <services>
    <service name="FirstWcfService.Service" 
              behaviorConfiguration="ServiceBehavior">
       <endpoint 
           address="FirstWcfService" 
           binding="netTcpBinding" 
           contract="FirstWcfService.IService"/>
       <endpoint 
           address="http://localhost:9102/FirstWcfService/mex"
           binding="mexHttpBinding" 
           contract="IMetadataExchange"  />
        ......
    </service>
</services>

Solution 2: define an HTTP base address, too:

 <services>
    <service name="FirstWcfService.Service" 
              behaviorConfiguration="ServiceBehavior">
       <endpoint 
           address="FirstWcfService" 
           binding="netTcpBinding" 
           contract="FirstWcfService.IService"/>
       <endpoint 
           address="mex"
           binding="mexHttpBinding" 
           contract="IMetadataExchange"  />
       <host>
           <baseAddresses>
               <add baseAddress="net.tcp://localhost:9101/"/>
               <add baseAddress="http://localhost:9102/"/>
           </baseAddresses>
       </host>
    </service>
</services>

Solution 3: use the mexTcpBinding instead

 <services>
    <service name="FirstWcfService.Service" 
              behaviorConfiguration="ServiceBehavior">
       <endpoint 
           address="FirstWcfService" 
           binding="netTcpBinding" 
           contract="FirstWcfService.IService"/>
       <endpoint 
           address="mex"
           binding="mexTcpBinding" 
           contract="IMetadataExchange"  />
        ......
    </service>
</services>

Any of those three options should should solve it.

A word of caution: I find it quite risky to call your service behavior configuration "ServiceBehavior"......

<serviceBehaviors>
    <behavior name="ServiceBehavior" >

My recommendation: call your first and default configuation just plain "Default" (or "DefaultBehavior")

<serviceBehaviors>
    <behavior name="Default" >

and only start giving out other names if you have multiple configurations.

Calling this ServiceBehavior just seems to be asking for trouble some time later on.....

Related Topic