Rest – Making a WCF Web Service work with GET requests

asp.netrestwcfweb-services

Background
I have created ASMX web services in the past and have been able to access the service from the web browser and Ajax GET requests using the address convention:
MyService.asmx/MyMethod?Param=xxx

I just got started using WCF and created a new web service in my ASP.NET project. It creates a file with the .svc extension such as MyService.svc.

Current Situation
I am able to consume the service using the WcfTestClient that comes with VS2008. I am also able to create my own WCF Client by either adding a service reference in another project or using the svcutil.exe commandline to generate the proxy and config file.

The Problem
When I try to use the service from a browser using MyService.svc/MyMethod?MyParam=xxx, I get a blank page without any errors.

What I have tried
I have already added a basicHttpBinding to the web.config and made it HttpGetEnabled in the behavior configuration. I also added the [WebGet(UriTemplate = "MyMethod?MyParam={MyParam}")] attribute to my operation contract.

I have already followed the information in this other stack overflow question:
REST / SOAP EndPoints for a WCF Service

However, I either get a blank page or an HTTP 404 Error after following those steps. There's nothing special about the code. I am just taking in a string as a parameter and returning "Hello xxx". This is a basic "Hello WCF World" proof-of-concept type thing.


UPDATE – Here's the relevant code

[ServiceContract]
public interface IMyService
{
    [WebGet(UriTemplate = "MyMethod/MyParam={MyParam}")]
    [OperationContract]
    string MyMethod(string MyParam);
}

Web.Config – system.serviceModel Section

<system.serviceModel>     
    <behaviors>
        <serviceBehaviors>          
            <behavior name="MyServiceBehavior">
              <serviceMetadata httpGetEnabled="true"  />
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyServiceBehavior" name="MyService">
        <endpoint address="" 
                       binding="wsHttpBinding" contract="IMyService" />
        <endpoint address="MyService.svc" 
                       binding="basicHttpBinding"  contract="IMyService" />
        <endpoint address="mex" 
                       binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>    
</system.serviceModel>

Best Solution

Looking at your web.config serviceModel section, I can see that you need to add a webHttpBinding and associate an endPointBehavior that includes webHttpGet.

Your operation contract is correct. Here's how your system.serviceModel config section should look in order for you to be able to consume the service from a GET HTTP request.

<system.serviceModel>     
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceMetadata httpGetEnabled="true"    />
                <serviceDebug includeExceptionDetailInFaults="true"/>          
            </behavior>
        </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="WebBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>    
    <services>      
      <service behaviorConfiguration="MyServiceBehavior" name="MyService">
        <endpoint address="ws" binding="wsHttpBinding" contract="IMyService"/>
        <endpoint address="" behaviorConfiguration="WebBehavior"
                  binding="webHttpBinding"
                  contract="IMyService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>    
</system.serviceModel>

Be sure to assign a different address to your wsHttpBinding endpoint, otherwise you will get an error saying that you have two endpoints listening on the same URI.

Another option is to leave the address blank in the wsHttpBinding, but assign a different address to the webHttpBinding service. However, that will change your GET address as well.

For example, if you assign the address as "asmx", you would call your service with the address "MyService.svc/asmx/MyMethod?MyParam=xxxx".

Related Question