WCF REST 4.0 PUT/POST/DELETE not working (400 Bad Request)

shuniar picture shuniar · Dec 14, 2011 · Viewed 8.9k times · Source

I have been working on setting up a WCF REST service in .NET 4.0. I have GET requests working, but any request that involves POSTing data to the server fails with a HTTP 400 Bad Request.

This is my simple service:

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1
{
    [WebGet(UriTemplate = "")]
    public string HelloWorld()
    {
        return "hello world";
    }

    [WebInvoke(UriTemplate = "", Method = "POST")]
    public string HelloWorldPost(string name)
    {
        return "hello " + name;
    }
}

My Web.config:

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

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

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <protocolMapping>
      <add scheme="http" binding="webHttpBinding" />      
    </protocolMapping>
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

</configuration>

And my global.asax:

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        RegisterRoutes();
    }

    private void RegisterRoutes()
    {
        RouteTable.Routes.Add(new ServiceRoute("Service1", new WebServiceHostFactory(), typeof(Service1)));
    }
}

Basically, everything is default from the template, but I've just simplified the Service1. I have tried both running it through the debugger and passing a request through Fiddler and running it in IIS and doing the same, as well as using a simple console application to fake the POST but I always get the 400 Bad Request error and I have no idea why. I've looked all over the internet and can't figure anything out.

I've tried both of the following request examples (neither work):

XML:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">String content</string>

JSON:

"String content"

Answer

Martin Owen picture Martin Owen · Dec 18, 2011

Are you setting the Content-Type header correctly in your request? For the XML request it should be text/xml and for the JSON it should be application/json. Your code works for me when I set the Content-Type in Fiddler.

You should also set the Accept header in your GET to either text/xml or application/json depending on what format you want the response to be in. It is okay for the POST as the server will assume that you want the response in the same format as the request, because you have set automaticFormatSelectionEnabled="true" in your web.config. There's more detail about format selection in WCF REST here: http://blogs.msdn.com/b/endpoint/archive/2010/01/18/automatic-and-explicit-format-selection-in-wcf-webhttp-services.aspx