0

I'm creating a rest api in visual studio express 2013.

I have 2 controllers: one for orders and one for clients.

I've already created the following:

/api/clients GET information about all clients

/api/clients/1 GET information about client with id = 1

/api/orders/10 GET information about order with id = 10

Now, I want to create this:

/api/clients/1/orders - GET information about all orders of client with id 1

I've read about attribute routing, but I can't make it work.

OrdersController.cs

[EnableCors(origins: "*", headers: "*", methods: "*")]
public class OrdersController : ApiController
{
    public Order Get(string id)
    {
        // ...
    }

    [Route("clients/{id}/orders")]
    public List<Order> GetByClient(string id)
    {
        // ...
    }
}

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Enable CORS
        config.EnableCors();

        //config.MapHttpAttributeRoutes();

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

RouteConfig.cs

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Like this, all of the other requests work properly, but when I try to access /api/clients/1/orders, I get the error HTTP Error 404.0 - Not Found. The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

But as soon as I uncomment config.MapHttpAttributeRoutes();, I'm no longer able to access any of the requests - they all return this:

<Error>
    <Message>An error has occurred.</Message>
<ExceptionMessage>
    The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace>
    at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes() at System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)
</StackTrace>
</Error>

What am I doing wrong here?

CodeFuller
  • 30,317
  • 3
  • 63
  • 79
Tirafesi
  • 1,297
  • 2
  • 18
  • 36
  • 2
    Try uncommenting `//config.MapHttpAttributeRoutes();` – Chetan Nov 16 '17 at 14:37
  • You are also missing a `[HttpGet]` attribute on the `GetByClient` action in `OrdersController` – Nkosi Nov 16 '17 at 14:46
  • @ChetanRanpariya did you even read what I wrote? – Tirafesi Nov 16 '17 at 14:50
  • @Nkosi My question is clear. I state what I have, what I want, and what my problem is. Not sure what it is you're not understanding. Also, [HttpGet] shouldn't be needed, as the method name starts with Get. – Tirafesi Nov 16 '17 at 14:50
  • 2
    I missed the last part. Sorry if I offended you. I am sure you tried the suggestion mentioned in the exception too. If not you can follow https://stackoverflow.com/questions/19969228/ensure-that-httpconfiguration-ensureinitialized – Chetan Nov 16 '17 at 14:55
  • 1
    https://stackoverflow.com/questions/25066147/error-with-webapi-2-0-routeattribute – Chetan Nov 16 '17 at 14:57
  • Other potential reason is that the Controller class does not end in "Controller". E.g.: "SomethingApi.cs" instead of "SomethingApiController.cs". Surely not the issue in this question, but google keeps bringing me here. – Mitch Mar 05 '21 at 00:04

2 Answers2

3

With routing attribute [Route("clients/{id}/orders")], you should access action GetByClient() not by /api/clients/1/orders url, but with /clients/1/orders. To have an original url just fix the routing:

[Route("api/clients/{id}/orders")]
public List<Order> GetByClient(string id)
CodeFuller
  • 30,317
  • 3
  • 63
  • 79
2

Uncomment your config.MapHttpAttributeRoutes() line, then in your Global.asax file, replace this:

WebApiConfig.Register(GlobalConfiguration.Configuration);

with this:

GlobalConfiguration.Configure(WebApiConfig.Register);

You can read about it here:

Attribute Routing in ASP.NET Web API 2

JuanR
  • 7,405
  • 1
  • 19
  • 30
  • This fixed the problem of not being able to access any of the requests, however, as pointed out by the other user, i still had the route path wrong. I wish I could appoint both of your answers as accepted... Thank you! – Tirafesi Nov 16 '17 at 15:06
  • 1
    The path would have never worked without you fixing the configuration. Your real issue was the global.asax. – JuanR Nov 16 '17 at 15:08