问题
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"
回答1:
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
回答2:
Your attributes should not be in the implementation, they should be in the operation contract. You also need to make sure you have any named parameters included in the UriTemplate. They are case sensitive so they have to match exactly.
IService.cs
[ServiceContract]
public class IService1
{
[WebGet(UriTemplate = "")]
[OperationContract]
public string HelloWorld();
[WebInvoke(UriTemplate = "/{name}", Method = "POST")]
[OperationContract]
public string HelloWorldPost(string name);
}
Service.cs
public class Service1 : IService
{
public string HelloWorld()
{
return "hello world";
}
public string HelloWorldPost(string name)
{
return "hello " + name;
}
}
You need to configure the service in your web.config file as well under System.ServiceModel
<system.serviceModel>
<services>
<service name="Service1">
<endpoint address="basic" binding="basicHttpBinding" contract="IService1" />
</service>
<services>
</system.serviceModel>
That's some of the main concepts and should get you started in the right direction. If you want a good test project to start out just use the "WCF Application" project template in VS2010. It has most of the required pieces wired in for you. Hope this helps!
来源:https://stackoverflow.com/questions/8507853/wcf-rest-4-0-put-post-delete-not-working-400-bad-request