8

I have WCF hosted SOAP service which I'm able to hit from the browser as well as from my SOAP client fine when making HTTP GET requests, however, when doing any HTTP POST requests, the response is a 404 Not Found.

My Web.config looks like:

<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" httpsGetEnabled="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="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
    <bindings>
        <wsHttpBinding>
            <binding>
                <security mode="Transport">
                    <transport clientCredentialType="Certificate" />
                </security>
                <readerQuotas maxDepth="15" maxStringContentLength="524288" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            </binding>
        </wsHttpBinding>
        <basicHttpBinding>
            <binding>
                <readerQuotas maxDepth="15" maxStringContentLength="524288" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            </binding>
        </basicHttpBinding>
    </bindings>
</system.serviceModel>

My service is defined in the markup using the .svc file as:

<%@ ServiceHost Language="C#" Debug="true" Service="Boca.WebServices.Billing.QBService" CodeBehind="QBService.svc.cs" %>

Again, I can hit my service using the browser and a SOAP client as follows using an HTTP GET but not with HTTP POST:

What am I doing wrong? Should I not be using the .svc markup and just define my service in the Web.config?

UPDATE:

When I "start debug" my WCF project from within VS 2010 using IIS Express on a localhost:8181 port, the HTTP POSTS to the service work. It's only when the service is hosted through IIS the HTTP POST to the service are being rejected or not found.

Huzaifa Tapal
  • 191
  • 1
  • 1
  • 7

2 Answers2

10

I've solved the problem. It, after all, was not an IIS issue rather an issue with the me not configuring the <basicHttpBinding> with <security> node. I din't thoroughly read about bindings and how they work, so I thought that adding the <wsHttpBinding> alongside the <basicHttpBinding> would add SSL support for WCF.

Doing so and configuring the default <wsHttpBinding> with the <security> node definitely allowed me to GET the SOAP metadata securely even though internally it was still using the <basicHttpBinding>, however POSTs were not supported.

I updated my configuration so that the transport clientCredentialType was set to None and that resolved the issue:

<bindings>
    <basicHttpBinding>
        <binding name="QBService_BasicHttpBinding">
            <security mode="Transport">
                <transport clientCredentialType="None" />
            </security>
            <readerQuotas maxDepth="15" maxStringContentLength="524288" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
    </basicHttpBinding>
</bindings>
Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
Huzaifa Tapal
  • 191
  • 1
  • 1
  • 7
2

Assuming you are using .NET 4 your service will be listening on one or more endpoints using basicHttpBinding - this is the default if you don't specify an endpoint when using HTTP

If you have only one service contract then your service will listen for HTTP POST at the address ending with .svc. If you have more than one service contract then it hosts each contract at an address like <path to .svc>/<serviceContractname>

The service is expecting a SOAP request so you will need to POST an XML document that matches SOAP 1.1 (basicHttpBinding defaults to this). The easiest way to achieve this is to build a proxy using Add Service Reference in a client project and make calls through the generated proxy class - the WCF plumbing will generate the appropriate message and POST it to the service

Richard Blewett
  • 6,089
  • 1
  • 18
  • 23
  • The issue is that doing an HTTP POST results in a 404 whereas doing an HTTP GET works. Also, I've noticed that if I debug my VS 2010 WCF Project using IIS Express from within VS 2010, the HTTP POSTS to the service work fine. It seems to be only when hosted through IIS that I'm seeing this behavior. – Huzaifa Tapal Jul 11 '11 at 19:28
  • I think it would be more useful to view it as "retrieving the metadata works but making a service request fails with a 404". I assume you are making the GETs using Add Service Reference or a browser and the POSTs using a request thought the generated proxy - is this correct? – Richard Blewett Jul 12 '11 at 05:44
  • Also, how many service contracts does your service implement? – Richard Blewett Jul 12 '11 at 05:45
  • The POSTs are being made by the QuickBooks Web Connector SDK through a client reference. My service implements 1 service contract with about 10 operations. – Huzaifa Tapal Jul 12 '11 at 20:39
  • In the WSDL what is the address of the service? Are you getting something in there that is not routable from the client? – Richard Blewett Jul 13 '11 at 06:06
  • The address in my wsdl seems like simply machinename/virdir instead of domain/virdir...and is unreachable from the client. Is there a way to configure that url? – Terry May 24 '16 at 16:09
  • You can put the DNS name in the address or base address for the endpoint/service e.g. - SO may contract that address – Richard Blewett May 25 '16 at 07:02
  • Actually - better check, are you hosting in IIS or self hosting? – Richard Blewett May 25 '16 at 07:06