Search code examples
c#.netjsonwcfwcf-rest

Why am I getting a "405 Method not allowed" error on "Put" operations through a WCF Resful service?


I've got a simple WCF service which takes json as input/output parameters. It works correctly as a SOAP based service and I get the expected results.

I have added RESTFul endpoints to the service. I'm using "Google-based" PostMan to test the service.

I can successfully call "Get" methods on the service and return JSON results:

 [OperationContract(IsOneWay = false)]
    [WebGet(UriTemplate = "/Test/{calcID}", 
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
    CalcResults GetTestResults(string calcID);

When I attempt to access my "Put" based methods I get a status of: 405 Method Not Allowed

The signature for the "Put" method:

 [OperationContract(IsOneWay = false)]
    [WebInvoke(Method = "Post",
        UriTemplate = "/GetCalculation", 
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
    CalcResults GetCalculation(CalcInput inputValues);

This is the output that I see in the PostMan output window:

<body>
   <div id="content">
      <p class="heading1">Service</p>
      <p>Method not allowed.</p>
   </div>
</body>

This is what my configuration settings look like for the endpoints for the RESTFul interface:

<system.serviceModel>
    <services>
      <service name="CalcServiceLibrary.CalcService">

        <endpoint address="regular" binding="wsHttpBinding" name="wsHTTPEndPoints"
          contract="CalcServiceLibrary.ICalcService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="json" binding="webHttpBinding" name="wsWebHTTPEndPoint"
                  contract="CalcServiceLibrary.ICalcServiceRESTful"
                  behaviorConfiguration="RESTfulBehavior" bindingConfiguration="crossDomain">
            <identity>
              <dns value="localhost" />
            </identity>          
        </endpoint>
      </service>
    </services>

    <bindings>
      <webHttpBinding>
        <binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="RESTfulBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>      
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

I'm sure that there is something that is not quite correct in my configuration definitions. I've researched several posts, but have not been able to come up with the solution.

NEW NOTE:: I've added the following simple endpoint to my service:

[OperationContract]
[WebInvoke(
    Method = "POST",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]
public string TestPost(string name)
{
    return "Hello " + name + "!";
}

I'm testing using Postman. Here is a screen shot of my Postman screen: Postman Input Screenshot

This is what I see in the output: Postman Output Screenshot

This feels like it has to be some sort of configuration issue. Can someone point me in the right direction as to what I'm doing wrong?


Solution

  • Looks like you're specifying post instead of put as the method in the declaration, perhaps change to:

    [OperationContract(IsOneWay = false)]
       [WebInvoke(Method = "PUT",
           UriTemplate = "/GetCalculation", 
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           BodyStyle = WebMessageBodyStyle.Bare)]
       CalcResults GetCalculation(CalcInput inputValues);