Search code examples
c#.netwcfwcf-binding

WCF service relative uri without .svc


I have a solution with 3 projects:

  • MEProject.WCF.ServiceLayer (Service-Implementation)
  • MEProject.WCF.HostConsole (Console Application which can host the service)
  • MEProject.WCF.HostIIS (WCF Service Application)

My goal is that I can switch between the 2 projects without changing the uri (the endpoint configurations) in the client project. Well, the problem is, if I start the console application, the endpoints are

http://localhost:8080/MultipleEndpointService/FirstEndpoint
http://localhost:8080/MultipleEndpointService/SecondEndpoint  

But if I start the WCF service application, the endpoints are

http://localhost:8080/MultipleEndpointService.svc/FirstEndpoint
http://localhost:8080/MultipleEndpointService.svc/SecondEndpoint

As you can see, the difference is the ".svc". Now my question: How can I tell the WCF service application to act like the console application and not to have the ".svc" in the uri?

Here is the code I use to get the multiple endpoints in the console application:

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
    serviceHostBase.ChannelDispatchers.ToList().ForEach(channelDispatcher =>
    {
        ChannelDispatcher dispatcher = channelDispatcher as ChannelDispatcher;
        if (dispatcher != null)
        {
            dispatcher.Endpoints.ToList().ForEach(endpoint =>
            {
                endpoint.DispatchRuntime.InstanceProvider = new CallBackInstanceProvider(serviceDescription.ServiceType, InstanceCreator);
            });
        }
    });
}

And here is the WCF service application web.config:

<system.serviceModel>
<services>
  <service name="MEProject.Service.WCF.HostIIS.MultipleEndpointService">
    <endpoint name="FirstEndpoint" address="FirstEndpoint" binding="basicHttpBinding" contract="MEProject.Service.WCF.ServiceLayer.IFirstEndpoint"/>
    <endpoint name="SecondEndpoint" address="SecondEndpoint" binding="basicHttpBinding" contract="MEProject.Service.WCF.ServiceLayer.ISecondEndpoint"/>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8080/MultipleEndpointService" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="False" />
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>

Thanks in advance for your response!


Solution

  • for running a WCF without the SVC extension you will need to use routing

    for example i have a service named MultipleEndpointService.svc and i want to get the service like the following: .../MultipleEndpointService/FirstEndpoint

    we can do it like this: Global.asax:

    public class Global : System.Web.HttpApplication
    {
    
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.Add(new ServiceRoute("MultipleEndpointService/FirstEndpoint", new ServiceHostFactory(), typeof(MultipleEndpointService)));            
    
        }
    }
    

    MultipleEndpointService.svc.cs:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class MultipleEndpointService : IMultipleEndpointService
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }
    
        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }
    }
    

    Web.config (for IIS7):

    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true">
            <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </modules>
    
        <handlers>
            <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd"/>
        </handlers>             
    
        <directoryBrowse enabled="true"/>
    </system.webServer>
    

    source