Search code examples
wcfjsonrest

C# 4.0 WCF REST JSON - HTTP GET CODE 400 Bad Request


When trying to create a simple service to return a simple JSON string by following several tutorials. I get stuck on two different machines with a HTTP Statuscode 400 bad request. Example tutorials RESTful WCF Service with JSON pt.1 & pt.2 - http://www.youtube.com/watch?v=5BbDxB_5CZ8

I have also Google and searched here (StackOverflow) for similar problem without success.

The problem is I get the 400 bad request when trying to do a sanity check to browse to the WCF service and execute the method. By compiling the service and browse this address: http://localhost:49510/Service1.svc/GetPerson Just like the tutorial. I have tried finding a solution for like 3 days. Any help is appreciated.

This is what I do.

First i create a new project a simple WCF Service application. I delete the default Service1.svc and add a new WCF Service, that generate a new Service1.svc and a IService1.cs

Here is the code for the interface (IService1.cs)

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebInvoke(Method="GET", BodyStyle=WebMessageBodyStyle.Bare, ResponseFormat=WebMessageFormat.Json, RequestFormat=WebMessageFormat.Json, UriTemplate="GetPerson")]
        Person GetPerson();
    }

    [DataContract(Name="Person")]
    public class Person
    {
        [DataMember(Name="name")]
        public string Name { get; set; }
    }
}

Here is the code for the Service1.svc

namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        public Person GetPerson()
        {
            return new Person() { Name = "Tobbe" };
        }
    }
}

And the Web.config is untouched and look likes this web.config

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

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <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="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

Solution

  • For REST WCF You have to do binding and endpoint setting in web.config

    Replace your whole web.config by following and it will work

    <?xml version="1.0"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <protocolMapping>
          <add scheme="http" binding="webHttpBinding"/>
        </protocolMapping>
        <behaviors>
          <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="false"/>
    
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior>
              <webHttp/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
     <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>  
     </configuration>
    

    You were remaining with following 2 things

    Use webHttpBinding (change default http port mapping to webHttpBinding)

    <system.serviceModel>
        <protocolMapping>
            <add scheme="http" binding="webHttpBinding"/>
        </protocolMapping>
        <behaviors>
    
    <system.serviceModel>
    

    Specify webHttp End Point Behaviors

    <system.serviceModel>
        -----
        </protocolMapping>
        <behaviors>
            <endpointBehaviors>
                <behavior>
                    <webHttp />
                </behavior >
            </endpointBehaviors>
        <behaviors>
        ------
    <system.serviceModel>