WCF REST, configure endopoint to return SOAP, XML and JSON

WCF is a great technology but unfortunatly it’s not so easy to configure it to work correctly.
I’ve spent many hours to understand exact how to configure WCF to gain the right result.

Creating a WCF it’s easy, and it’s work like a old WebService (.asmx)

But how can i configure it to return json or xml?

There are 3 solutions:

Return xml or json by code

[ServiceContract]
public interface IMyWCFSvc
{
    [OperationContract]
    [WebGet(UriTemplate="/{username}")]
    //[WebGet UriTemplate="?username={username}"]
    List<MyDTO_Object> GetUser(string username);
}

First of all add the attribute [WebGet], adding this attribute you indicate that this method can be used REST.
Then specify the UriTemplate pattern you prefer to pass the parameter to the method, I use a “routed pattern” and I’ve commented a “QueryString pattern”

Now we have to say what ResponseFormat we prefer, so transform all like this:

[ServiceContract]
public interface IMyWCFSvc
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare UriTemplate="/{username}" ResponseFormat = WebMessageFormat.Json)]
    List<MyDTO_Object> GetUserJSON(string username);

    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare UriTemplate="/{username}" ResponseFormat = WebMessageFormat.Xml)]
    List<MyDTO_Object> GetUserXML(string username);
}

I’ve specifyed two methods, one that return XML and one that return JSON.
If you need only xml or json specify only one method 🙂

Then implement this Interface like this:

public class MyWCFSvc : IMyWCFSvc
{
    public List<MyDTO_Object> GetUserJSON(string username)
    {
        return GetUserInternal(username);
    }

    public List<MyDTO_Object> GetUserXML(string username)
    {
        return GetUserInternal(username);
    }

    protected List<MyDTO_Object> GetUserInternal(string username)
    {
        // implementation code...
    }
}

Now this wcf service is configured correctly and can be used by calling these address:

http://localhost:1234/MyWCFSvc.svc/GetUserJSON/MikyMouse
http://localhost:1234/MyWCFSvc.svc/GetUserXML/MikyMouse

Drawback:
Specify one method for XML, and other to JSON to get the same result but only serialized in different manner.
This service does not respond to soap but only REST.

Return xml or json by Web.config

What I explain now is how to configure a WCF service that can be user via soap or via REST and return JSON and XML without write any additional line of code

Like before we have to configure the interface to permit REST:

[ServiceContract]
public interface IMyWCFSvc
{
    [OperationContract]
    [WebGet(UriTemplate="/{username}")]
    List<MyDTO_Object> GetUser(string username);
}

Now I define only this and not two method.

Then implement it in code like standard WCF service

public class MyWCFSvc : IMyWCFSvc
{
    public List<MyDTO_Object> GetUser(string username)
    {
        // implementation code...
    }
}

and now go to web config to configure JSON or XML serialization.
To gain the desired result I’ve to specify multiple endpoint.
An endpoint is an “address” in wich the service can respond with the behavavior specifyed

<system.serviceModel>
    <services>
      <service name="MyWCFService.MyWCFSvc" >

	<!-- these endpoint are necessary to return SOAP service -->
        <endpoint address=""
                     binding="basicHttpBinding"
                     contract="MyWCFService.IMyWCFSvc" />
        <endpoint address="mex" 
                  contract="IMetadataExchange" binding="mexHttpBinding"/>
        
        <!-- REST service return json -->
        <!--To call this endpoint use: [service].svc/json/[method_Name]-->
        <endpoint address="json"
                  binding="webHttpBinding" behaviorConfiguration="jsonBehavior"
                  contract="MyWCFService.IMyWCFSvc" />

        <!-- REST service return xml -->
        <!--To call this endpoint use: [service].svc/xml/[method_Name]-->      
        <endpoint address="xml"
                  binding="webHttpBinding" behaviorConfiguration="xmlBehavior"
                  contract="MyWCFService.IMyWCFSvc" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>

      <endpointBehaviors>
          <behavior name="jsonBehavior">
            <enableWebScript/> <!-- use JSON serialization -->
          </behavior>
          <behavior name="xmlBehavior">
            <webHttp/> <!-- use XML serialization -->
          </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Ok I’ll explain all.
I’ve specifyed 4 endpoint.

The first and the second are necessary to use SOAP service and generate proxy classes.
Notice that in the first I specifyed binding=”basicHttpBinding” to get SOAP response

The third and the fourth I specifyed binding=”webHttpBinding” to get be called by REST

Now to return JSON or XML I’ve also add behaviorConfiguration; behaviorConfiguration=”jsonBehavior” for json service and behaviorConfiguration=”xmlBehavior” for xml service.
You’ll find jsonBehavior and xmlBehavior in the endpointBehaviors

In xmlBehavior I used webHttp to serialize in XML
In jsonBehavior I used enableWebScript to serialize in JSON

Ok I’ve explained all but now how can we call this?
We have to use the endpoint address so:

at this address will respond the SOAP service and generate the proxy classes
http://localhost:1234/MyWCFSvc.svc/

at this address will respond the JSON REST service
http://localhost:1234/MyWCFSvc.svc/json/%5Bmethod%5D
http://localhost:1234/MyWCFSvc.svc/json/GetUser/mikyMouse

at this address will respond the XML REST service
http://localhost:1234/MyWCFSvc.svc/xml/%5Bmethod%5D
http://localhost:1234/MyWCFSvc.svc/xml/GetUser/mikyMouse

This service can be used to respond to any request!
The only difficult is know how to configure it in web.config but capy all code and

Automatic configuration (suggested framework 4.0)

This is a great solution but can be used only with framework 4.0

With this we can get the same result as before but with less configuration

Use the same interface

[ServiceContract]
public interface IMyWCFSvc
{
    [OperationContract]
    [WebGet(UriTemplate="/{username}")]
    List<MyDTO_Object> GetUser(string username);
}

and the same implementation

public class MyWCFSvc : IMyWCFSvc
{
    public List<MyDTO_Object> GetUser(string username)
    {
        // implementation code...
    }
}

Now like before go to the web.config

<system.serviceModel>
    <services>
      <!--behaviorConfiguration="serviceBehavior"-->
      <service name="MyWCFService.MyWCFSvc" >
	<!-- these endpoint are necessary to return SOAP service -->
        <endpoint address=""
                     binding="basicHttpBinding"
                     contract="MyWCFService.IMyWCFSvc" />
        <endpoint address="mex" 
                  contract="IMetadataExchange" binding="mexHttpBinding"/>
        
        <!--To call this endpoint use: [service].svc/rest/[method_Name]-->
        <endpoint address="rest"
                  binding="webHttpBinding" behaviorConfiguration="restfulBehavior"
                  contract="MyWCFService.IMyWCFSvc" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restfulBehavior">
          <webHttp automaticFormatSelectionEnabled="true"  />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

Wow this configuration is very compact.
First and second endpoint like before is to SOAP service.
The third endpoint is the REST service and use the restfulBehavior behavior.
The great magic is in restfulBehavior configuration, in this line:

<webHttp automaticFormatSelectionEnabled="true"  />

With this attribute the endpoint return JSON or XML.
The service choose what serialization use by looking on Content-type Header request.
If you call the service with Content-type = “application/xml” the service return xml,
If you call the service with Content-type = “application/json” the service return json,

If you call the service by code using webClient:

WebClient.Headers["Content-type"] = "application/json"

If you call the service by jquery ajax:

$.ajax({
    type: "GET",
    contentType: "application/json; charset=utf-8",
    cache: false,
    url: "http://localhost:1234/MyWCFSvc.svc/rest/GetUser/mikyMouse",
    beforeSend: function () { },
    complete: function () { },
    error: function (e, e1, e2) {
        ...
    },
    success: function (result) {
        ...
    }
});

We have to use the endpoint address so:

at this address will respond the SOAP service and generate the proxy classes
http://localhost:1234/MyWCFSvc.svc/

at this address will respond the JSON or XML REST service
http://localhost:1234/MyWCFSvc.svc/rest/%5Bmethod%5D
http://localhost:1234/MyWCFSvc.svc/rest/GetUser/mikyMouse

Annunci

Informazioni su Andrea Regoli

Project Manager .Net Developer WPF WP7 Asp.Net c# javascript ajax SQL sharepoint
Questa voce è stata pubblicata in Asp.Net, c#, WCF e contrassegnata con , , , , , , , , . Contrassegna il permalink.

4 risposte a WCF REST, configure endopoint to return SOAP, XML and JSON

  1. Miguel Morais ha detto:

    Nice article. Very well explained.

  2. Murthy ha detto:

    Thanks….for very clean and clear explanation.

  3. sdfds ha detto:

    Clear and well organized

  4. Ragu ha detto:

    Very Nice and Useful…….

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...