I have a WCF RESTful web service (using the webHttpBinding) running under IIS, exposed via an SVC file (accessed at http://projectserver/BlarghService/BlarghService.svc).
I can access service endpoints through the URI templates defined on each service by using the BlarghService.svc file, like so:
http://projectserver/BlarghService/BlarghService.svc/accounts/
http://projectserver/BlarghService/BlarghService.svc/accounts/342432
Both of these work fine.
However it’s important I remove implementation details from the URIs, so I used IIS URI rewriting module and set up a wildcard rewriting rule which tacks everything after /BlarghService/ to the end of BlarghService.svc, so the following are transformed into the earlier representations:
http://projectserver/BlarghService/accounts/
http://projectserver/BlarghService/accounts/342432
However, when I request these resources I get 404 errors. These are not IIS-generated 404 errors, but those generated by ASP.NET itself (so IIS is correctly rewriting the URL). However ASP.NET decides to check if the specified file (“BlarghService.svc/accounts/342432”) exists in the filesystem which it should be passing it on to my web service.
But the strange thing is when I copy the reported “Requested URL” (from the ASP.NET 404 error) back into the address bar, it works fine.
So what’s going on?
EDIT: Here is my web.config (located in the “BlarghService” directory)
<system.web>
<compilation debug="true" />
<authentication mode="None" />
<customErrors mode="Off" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<!-- Currently ASP.NET steps in says it's a 404 error when it should be handled by BlarghService.svc, I've no idea why. -->
<rewrite>
<rules>
<rule name="BlarghServiceRewriteRule" patternSyntax="Wildcard">
<match url="*" />
<action type="Rewrite" url="BlarghService.svc/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://projectserver/BlarghService" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<services>
<service name="Foo.Blargh.Api.BlarghService" behaviorConfiguration="BlarghServiceBehavior">
<endpoint name="BlarghEndpoint" address="BlarghService.svc" behaviorConfiguration="BlarghEndpointBehavior" binding="webHttpBinding" contract="RH.Blargh.Api.BlarghService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BlarghServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="BlarghEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
UPDATE: It turns out that WCF can only respond on one particular HTTP host header at a time, and that my URL rewriting was involved in responding to some host headers but not others. By standardising on a single set of host-headers and reformulating my rewrite rules accordingly it started working.