WCF and JSON binding

sebastian.roibu picture sebastian.roibu · Mar 23, 2012 · Viewed 12.8k times · Source

I am trying to create a wcf service that returns json. I have some problems with my config file and i also don't know how to test it.

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="false" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="ContactLibraryJSON.ContactLibrary">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="JSONEndpointBehavior"
          contract="ContactLibraryJSON.IContactServiceJSON" />
        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://192.168.1.31/ContactLibraryJSON" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="JSONEndpointBehavior">
          <webHttp/>
        </behavior>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above 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="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

I still get

"Cannot add the behavior extension webhttp to the service behavior names JSONEndpointBehavior because the underlying behavior type does not implement the IServiceBehaviorInterface"

Contact is defined like :

[DataContract(Name="Contact")]
public class Contact
{        
    [DataMember(Name="FirstName")]
    public string firstName=null;
    [DataMember(Name="LastName")]
    public string lastName=null;
    [DataMember(Name="Email")]
    public string email=null;
    [DataMember(Name = "Age")]
    public int age = 0;
    [DataMember(Name = "Street")]
    public string street=null;
    [DataMember(Name = "City")]
    public string city=null;
    [DataMember(Name = "Country")]
    public string country=null;
}

IContactService is defined like :

[ServiceContract]
public interface IContactServiceJSON
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, UriTemplate = "")]
    Contact GetContact();        
}

The implementation of GetContact:

public Contact GetContact()
{
    return new Contact()
    {
        firstName = "primulNume",
        lastName = "alDoileaNume",
        age = 33,
        city = "Cluj",
        country = "Romania",
        email = "[email protected]",
        street = "Bizusa 8"
    };
}

My service runs on another computer in my lan. Base address is like: http://192.168.1.xxx/ContactLibraryService. ContactLibraryService is hosted by IIS and is converted to an application.

Answer

carlosfigueira picture carlosfigueira · Mar 23, 2012

You need to add the <webHttp/> to the list of endpoint behaviors. Also, the endpoint needs to use the webHttpBinding. And finally, to respond to GET HTTP requests, you need to use the WebGet attribute (instead of WebInvoke(Method="GET").

  <system.serviceModel> 
    <services> 
      <service name="ContactLibrary.ContactLibrary"> 
        <endpoint address=""
                  binding="webHttpBinding"
                  behaviorConfiguration="JSONEndpointBehavior" 
                  contract="ContactLibrary.IContact"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
        <endpoint address="ws"
                  binding="wsHttpBinding"
                  bindingConfiguration="" 
                  contract="ContactLibrary.IContact" /> 
        <host> 
          <baseAddresses> 
            <add baseAddress="http://localhost/ContactLibrary" /> 
          </baseAddresses> 
        </host> 
      </service> 
    </services> 
    <behaviors> 
      <endpointBehaviors> 
        <behavior name="JSONEndpointBehavior"> 
          <webHttp/> 
        </behavior> 
      </endpointBehaviors> 
      <serviceBehaviors> 
        <behavior> 
          <!-- To avoid disclosing metadata information,  
          set the value below to false and remove the metadata endpoint above 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="true"/> 
        </behavior> 
      </serviceBehaviors> 
    </behaviors> 
  </system.serviceModel> 

And the service contract:

[ServiceContract]  
public interface IContact  
{  
    [OperationContract]  
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, UriTemplate = "contact")]  
    Contact GetContact(int idContact);        
}