Search code examples
asp.net-mvcasp.net-web-apiasp.net-mvc-routing

Web API controller in subfolder not being found with attribute routing


I have a controller in this folder structure:

Site
-Controllers
--API
---EventsController.cs

The EventsController.cs contains this:

[RoutePrefix("api")]
public class EventsController : Controller
{
    [Route("event")]
    public ActionResult Index()
    {
        return View("~/Views/Home/Index.cshtml");
    }

The WebApiConfig.cs contains this:

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

    // Web API routes
    config.MapHttpAttributeRoutes();

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

When I run the site from Visual Studio and try to access http://127.0.0.1:8080/api/event I see nothing but this error:

<Error>
  <Message>
    No HTTP resource was found that matches the request URI 'http://127.0.0.1:8080/api/event'.
  </Message>
  <MessageDetail>
    No type was found that matches the controller named 'event'.
  </MessageDetail>
</Error>

If I comment out the config.Routes.MapHttpRoute line to make WebApiConfig.cs as the following, the URL above works:

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

    // Web API routes
    config.MapHttpAttributeRoutes();

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

What am I doing wrong? What is it that causes the attribute routing to fail when the DefaultApi route is configured? I have tried placing it before/after the config.MapHttpAttributeRoutes(); and neither works.

As an aside, I have manually built up this project while reading the following article, which has the same structure of MVC/Web API project and which does work. I just can't figure out what I've done differently.

http://www.codemag.com/Article/1605081


Solution

  • Thanks to @phil-cooper the answer was to inherit the correct base class in the api controller.