ASP.NET WebAPI returning Http 405

4

I have a WebApi controller

[RoutePrefix("api/invitations")]
public class InvitationsApiController : ApiController

And an action method:

[Route]
[HttpPost]
public IHttpActionResult Create([FromBody] CreateCommand command)

When i try to POST to http://host/api/invitations i get a "“405 Method Not Allowed”

But when I use another route like:

[Route("test")]
[HttpPost]
public IHttpActionResult Create([FromBody] CreateCommand command)

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
    SetupFormatters(config);

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi", 
        routeTemplate: "api/{controller}/{id}", 
        defaults: new { id = RouteParameter.Optional });
}

And make a POST to http://host/api/invitations/test its working. I have controllers that works just perfect when requesting to "root".

More details on Http error:

HTTP Error 405.0 - Method Not Allowed The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.

Detailed Error Information: 
Module    DefaultDocumentModule
Notification    ExecuteRequestHandler  
Handler    StaticFile  Error
Code    0x80070001  
Requested URL   http://localhost:8008/api/invitations  
Physical Path <removed>   
Logon Method  Anonymous  
Logon User    Anonymous

Any suggestions what might be wrong?

c#
asp.net
iis
asp.net-web-api
iis-modules
asked on Stack Overflow Sep 1, 2015 by Rune Jensen • edited Sep 2, 2015 by haim770

2 Answers

2

Change your controller RoutePrefix declaration to Route at the controller level:

[Route("api/invitations")]
public class InvitationsApiController : ApiController

RoutePrefix doesn't add the route to the route table. This means, that if you want to use RoutePrefix, you'll have to prefix each action by itself, for example:

[RoutePrefix("api/invitations")]
public class InvitationsApiController : ApiController

[Route("")]
[HttpPost]
public IHttpActionResult Create([FromBody] CreateCommand command)
answered on Stack Overflow Sep 1, 2015 by Yuval Itzchakov • edited Sep 1, 2015 by Yuval Itzchakov
2

The problem is that you're having a physical directory that is matching your route (/api/invitations). Because such physical directory exists, IIS native DirectoryListingModule and DefaultDocumentModule modules (that are not allowing the POST verb) are taking over the request before the TransferRequestHandler (that is used by MVC and WebAPI) is able to handle it.

There is no reason to put your InvitationsController.cs in the same directory stucture that is going to match the requested route. That's why we have routing in the first place, to be able to register routes dynamically regardless of the physical location of the controller.

The common convention (that is also the default WebAPI template structure) is to put your controllers in the ~/Controllers directory (or ~/Controllers/Api). But you can actually put them in any directory as long as they're getting compiled as part of the project.

answered on Stack Overflow Sep 2, 2015 by haim770 • edited Sep 9, 2015 by haim770

User contributions licensed under CC BY-SA 3.0