简体   繁体   中英

WCF Application returning 400 Bad Request when hosted on IIS7

I have written a WCF web service using C# and Visual Studio 2008.

When I run it using the built in development web server, I am able to view the results of the various methods by browsing to the URL specified in the [WebGet(UriTemplate = "..")] attribute of the service contract.

Specifically, I have a method that matches the "/" URL, and returns a plain HTML file.

However when I deploy to IIS, running on Windows Server 2008, this method returns the standard "You have created a service" page.

If I try to execute any of my other methods, using the URI templates I specified, for example:

api.hostname.com/Service.svc/method/param

The server returns 400 Bad Request.

The system.serviceModel section of my live web.config looks like this:

 <system.serviceModel>
   <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
   <services>
       <service name="RootNamespace.Api.EventService"
           behaviorConfiguration="RootNamespace.Api.EventServiceBehaviour" >
        <endpoint address="" 
                  binding="wsHttpBinding" 
                  contract="RootNamespace.Api.IEventService" />
        <endpoint address="mex" 
                  binding="mexHttpBinding" 
                  contract="IMetadataExchange" />
        <host>
          <baseAddresses>
           <add baseAddress="http://api.hostname.com" />
         </baseAddresses>
       </host>
     </service>
   </services>
   <behaviors>
     <serviceBehaviors>
       <behavior name="RootNamespace.Api.EventServiceBehaviour">
         <serviceMetadata httpGetEnabled="true" />
         <serviceDebug includeExceptionDetailInFaults="true" />
       </behavior>
     </serviceBehaviors>
   </behaviors>
</system.serviceModel>

I wondered if the request wasn't getting as far as the WCF service, and was being blocked by another handler in IIS but the fact that it's returning different content for the root URL leads me to suspect I'm doing something else wrong here.

Update...

I have managed to progress slightly with a revised web.config:

<behaviors>
  <serviceBehaviors>
    <behavior name="RootNamespace.Api.EventServiceBehavior">
      <serviceMetadata httpGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="WebBehavior">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

<services>
  <service behaviorConfiguration="RootNamespace.Api.EventServiceBehavior"
           name="RootNamespace.Api.EventService">
    <endpoint address="" 
              binding="webHttpBinding" 
              behaviorConfiguration="WebBehavior"                     
              contract="RootNamespace.Api.IEventService">
    </endpoint>
  </service>
</services>

This is obviously significantly different from my first attempt, however the goal remains the same - I want to use a web browser to navigate to the URLs defined in the WebGet attributes of my service contract (IEventService).

Using this web config, rather than getting a 400 error, I now recieve a 403 forbidden error for the methods I have defined. For methods that do not exist, I recieve, correctly, an 'Endpoint not found' message. This makes me think that I have things running correctly but am just suffering from some sort of authentication issue at the application layer.

I'm also getting the feeling that I'm making this too complicated. This works without any kind of configuration in the Visual Studio web server after all.

I think your problem is this:

  • if you have service metadata enabled and have the httpGetEnabled=true in your config (and you do), then hitting the base address ( baseAddress="http://api.seetickets.com" ) will render out the metadata "you have a service" page. This is default WCF behavior.

  • you have an intro html page that "lives" at the same address --> you have a conflict

You can do two things, really:

  • disable the httpGetEnabled on your service metadata

or:

  • move your intro page to another address, eg http://api.seetickets.com/intro or something (by setting the UriTemplate="....." on the service method)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM