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

血红的双手。 提交于 2019-12-13 16:00:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!