Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hosting WCF soap and rest endpoints side by side

Tags:

rest

soap

wcf

I have written a service that I would like expose both via rest and soap. Everything I read about WCF 4.0 says that I just need to expose 2 endpoints with differing behaviors to do this. But I cannot get it to work.

Here is my service contract:

[ServiceContract]
public interface MyService
{
    [OperationContract]
    [WebGet(UriTemplate="data/{value}")]
    string GetData(string value);
}

Here is my web.config:

<?xml version="1.0"?>
<configuration>

    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>

        <services>
            <service name="MyService">
                <endpoint name="mex" address="mex" binding="mexHttpBinding" contract="MyService"/>
                <endpoint address="rest" behaviorConfiguration="restBehavior" binding="webHttpBinding" contract="MyService" />
                <endpoint address="soap" behaviorConfiguration="soapBehavior" binding="basicHttpBinding" contract="MyService" />
            </service>
        </services>

        <behaviors>

            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>

            <endpointBehaviors>
                <behavior name="restBehavior">
                    <webHttp automaticFormatSelectionEnabled="true" helpEnabled="true" />
                </behavior>
                <behavior name="soapBehavior" />
            </endpointBehaviors>

        </behaviors>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>

    </system.serviceModel>

    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>

</configuration>

I am using routing to define my service url:

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

Is there something that I am doing wrong here? I could really use some help.

like image 985
Troy Avatar asked Jul 29 '10 19:07

Troy


People also ask

How do I enable rest and SOAP on the same WCF service?

So how to enable both SOAP and REST services in the same WCF service. STEP 1: Create a new WCF service application. Configure service for both basicHttpBinding and webHttpBinding, So in Web. Config file define two endpoints - one each for SOAP and REST.

Is WCF service REST or SOAP?

WCF services use SOAP by default, but the messages can be in any format, and conveyed by using any transport protocol like HTTP,HTTPs, WS- HTTP, TCP, Named Pipes, MSMQ, P2P(Point to Point) etc.

How many endpoints can a WCF Service have?

The service configuration has been modified to define two endpoints that support the ICalculator contract, but each at a different address using a different binding.

Is WCF same as SOAP?

In ASP.NET Development services, SOAP messages are exchanged over HTTP, but WCF services can exchange the message using any format over any transport protocol. Though, SOAP is a default format that WCF uses. 10. WCF services have timeouts by default that can be configured.


3 Answers

I never found the "right" way to do this in configuration but was able to use the routing engine to accomplish this.

My global asax file now looks like this:

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

and my config like this: (to enable the rest help pages)

<system.serviceModel>

    <standardEndpoints>
        <webHttpEndpoint>
            <standardEndpoint automaticFormatSelectionEnabled="true" helpEnabled="true"/>
        </webHttpEndpoint>
    </standardEndpoints>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>

</system.serviceModel>

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

I like that this is in line with the asp.net MVC model more and requires little config. Additionally doing it this way allowed me to remove the .svc files from my project entirely which is also a plus IMO.

like image 140
Troy Avatar answered Oct 28 '22 07:10

Troy


How are you hosting your WCF service?? In IIS, you need a virtual directory and a MyService.svc file somewhere to enable service activation.

If you remove the ServiceRoute for now (to simplify matters), you should be able to reach your SOAP service endpoint at:

http://YourServer:Port/YourVirtualDirectory/YourService.svc/soap

and your REST service should be at

http://YourServer:Port/YourVirtualDirectory/YourService.svc/rest/data/{value}

(where you supply some arbitrary value for {value}).

What exactly is not working in your case??

You can try and test your SOAP endpoints using the WCF Test Client, while you should be able to hit the REST url in any browser.

like image 38
marc_s Avatar answered Oct 28 '22 07:10

marc_s


This is possible to do in configuration. From msdn forum thread by user Ladislav Mrnka: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/4e95575f-1097-4190-80dd-7a0f96d73f6e

<system.serviceModel>
 <behaviors>
  <endpointBehaviors>
    <behavior name="REST">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="iSell.Prospects.ProspectBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service behaviorConfiguration="iSell.Prospects.ProspectBehavior" name="iSell.Prospects.ProspectService">
    <endpoint address="" behaviorConfiguration="REST" binding="webHttpBinding" contract="iSell.Prospects.ProspectService" />
    <endpoint address="soap" binding="basicHttpBinding" contract="iSell.Prospects.ProspectService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
 </services>
</system.serviceModel>
like image 28
yzorg Avatar answered Oct 28 '22 07:10

yzorg