7

I've got a few methods, which I want to follow a specific pattern for their URLs.

Basically there's restaurants, which have IDs, and a collection of Terminals under them.

I'm trying to get the following sort of pattern to emerge: api/Restaurant - get all Restaurants api/Restaurant/Bobs - gets the restaurant with the ID of Bobs api/Restaurant/Bobs/terminals - get all terminals in bobs restaurant api/Restaurant/bobs/terminals/second - get the terminal with the ID of second in the restaurant bob

I've got the methods to do this, and I've assigned the Route attribute to each as follows:

    [HttpGet]
    public IEnumerable<IRestaurant> Get()
    {
        //do stuff, return all
    }

    [HttpGet]
        [Route("api/Restaurant/{restuarantName}")]
        public IRestaurant Get(string restaurantName)
        {
           //do stuff
        }

    [HttpGet]
    [Route("api/restuarant/{restaurantName}/terminals")]
    public IEnumerable<IMiseTerminalDevice> GetDevices(string restaurantName)
    {
       //do stuff
    } 

    [HttpGet]
    [Route("api/restaurant/{restaurantName}/terminals/{terminalName}")]
    public IMiseTerminalDevice GetDeviceByName(string restaurantName, string terminalName)
    {
        //do stuff
    }

However only my basic GET (api/Restaurant) is working. My WebAPI config is the default, and reads

    config.MapHttpAttributeRoutes();

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

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

Anybody know where I'm going wrong? All other methods return routing mismatch (restaurant with ID) or a 404.

Thanks in advance!

5
  • what did you mean by and reads config.MapHttpAttributeRoutes();?...are you calling config.MapHttpAttributeRoutes() because this is the one which probes controllers and registers attribute routes in the route table...also note that requests matching conventional routing will never match controllers/actions decorated with attribute routes.. Commented Aug 4, 2014 at 3:42
  • @Mathieson Could you please add post your request ? I have tried your APIs with the default template and it worked fine. Commented Aug 4, 2014 at 4:30
  • Yes, that section is the value of the WebApiConfig class - fixed formatting to make it clearer. Commented Aug 4, 2014 at 4:30
  • @Toan - sure! The url localhost:4675/api/restaurant returns the proper JSON. The url localhost:4675/api/restaurant/bob fires the controller constructor, and returns "{"Message":"No HTTP resource was found that matches the request URI 'localhost:4675/api/restaurant/… action was found on the controller 'Restaurant' that matches the request."}" The url localhost:4675/api/restaurant/bob/terminals just returns 404, and does not fire the controller constructor. Commented Aug 4, 2014 at 4:33
  • 1
    Maybe the "restuarant" typo doesn't help. Commented Jun 20, 2016 at 10:58

1 Answer 1

11

I have just created the default WEB API project which includes a ProductsController. Next, I pasted your api methods in.

  public class ProductsController:ApiController
    {



        [HttpGet]
        [Route("api/Restaurant/{restaurantName}")]
        public IHttpActionResult Get(string restaurantName)
        {
            //do stuff
            return Ok("api/Restaurant/{restuarantName}");
        }

        [HttpGet]
        [Route("api/restuarant/{restaurantName}/terminals")]
        public IHttpActionResult GetDevices(string restaurantName)
        {
            //do stuff
            return Ok("api/restuarant/{restaurantName}/terminals");
        }

        [HttpGet]
        [Route("api/restaurant/{restaurantName}/terminals/{terminalName}")]
        public IHttpActionResult GetDeviceByName(string restaurantName, string terminalName)
        {
            //do stuff
            return Ok("api/restaurant/{restaurantName}/terminals/{terminalName}");
        }
    }

Finally, I used Fiddler to make an request

**http://localhost:9969/api/restuarant/Vanbeo/terminals**

and everything works fine!

System Configs: Visual Studio 2013, WEB API 2.2, Net 4.5

Could you please retry with an empty project?

PS: I have to post this as an answer because there is not enough space in the comment!

Sign up to request clarification or add additional context in comments.

3 Comments

I created a new WebAPI project, and replaced the ValuesController method with the code above - now I find that localhost:3322/API/restaurant/bob returns correctly. However localhost:3322/API/restaurant/bob/terminals returns a 404
Can you just upgrade your Web API package to version 2.2 and retry again?
WebAPI is at 2.2. I think there's a problem with the method names - changing my signature to [Route("api/restaurants/{restaurantName}/{terminalName}")] [Route("api/restaurants/{restaurantName}/terminals/{terminalName}")] [HttpGet] public IHttpActionResult GetTerminalByName(string restaurantName, string terminalName) has enabled me to get to the method at least. I've refactored to move to a larger aggregate root of Restaurant, so this can be a good way to sidestep the issue. Still frustrating though - even the RouteDebugger isn't showing much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.