I have an existing ASP.NET Web API 2 project that was previously served under route prefix /api/ (example.com/api/Users), but now it needs to be moved directly under the root (example.com/Users).
The problem is that now some of the routes match physical directories in the project root, and IIS tries to serve those directories when making such conflicting request.
This is what the project structure looks like:
MyApi/
App_Start/
Controllers/
Models/
...
Permissions/
...
Global.asax
Global.asax.cs
...
Web.config
The routes are mapped using attribute routes: config.MapHttpAttributeRoutes();
And here's a simplified sample of a problematic controller:
namespace MyApi.Controllers
{
[RoutePrefix("Permissions")]
public class PermissionController
{
[Route("")]
[HttpGet]
[ResponseType(typeof(IEnumerable<Permission>))]
public IHttpActionResult Get()
{
return ...
When a request is made to example.com/Permissions, IIS first responds with a 301 redirect to example.com/Permissions/ (trailing slash) and then with:
IIS 10.0 Detailed Error
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Detailed Error Information:
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x00000000
All other controllers without conflicting directory names work as expected.
I've tried both enabling and disabling runAllManagedModulesForAllRequests, I've tried adding and removing handlers like this:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
And I've even tried removing the StaticFile handler, but nothing I've tried so far has worked.
This is the Web.config currectly. It is identical to what Visual Studio 2015 generates by default when creating a new empty Web API 2 project:
...
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
...
So can I prevent IIS from trying to serve physical files inside the project? The API should only serve dynamically generated content from the controllers.