0

Can someone help me fill in the blanks with my GET methods for webapi. I want to pass in no parameters and get all results. Pass in an int and get a single result and pass in a named parameter to filter by a typeId / zoneId or both but am struggling to get this to work.

TimeController : ApiController

// Time/  

//Time/1

//Time/typeId=1

//Time/zoneId=1

Time/typeId=1&zoneId=1

The closest I got was with

Global

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

        RouteTable.Routes.MapHttpRoute(name: "TemplateTimeApi",
           routeTemplate: "api/{controller}/{typeId}/{zoneId}",
           defaults: new {typeId = RouteParameter.Optional, zoneId = RouteParameter.Optional }
           );

Controller

 List<TimeView> Get(int typeId, int? zoneId = null)

 TimeView Get(int id)

but I get a 404 on no parameters.

I can change one of the parameters to a string if the issue is with two integers, however, I would prefer to understand the issue and get it to work.

PMC
  • 4,698
  • 3
  • 37
  • 57

2 Answers2

2

// Time/

If you take a look your routing table: the first routing is matched, but you don't have action with no parameter => 404 thrown.

//Time/1

Run correct, the first route is matched, in here, it choose the action: TimeView Get(int id) becasue of the name: id on routing match to paramter "id" with this method. Remember, Web API bases heavily on naming convention.

//Time/typeId=1

//Time/zoneId=1

Wrong URL => 404 thrown, I guess you would like to put as query string, should be: Time?typeId=1 But even wrong because, the first routing is match with parameter "Id", not "typeId", so no action method was found.

Time/typeId=1&zoneId=1

Wrong URL too, the same reason with above.

The correct URL you should have: GET Time/1/1 will match with your second route.

For more understanding on routing and action: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

Community
  • 1
  • 1
cuongle
  • 74,024
  • 28
  • 151
  • 206
  • Thanks Cuong, I need to re-read this as obviously not getting it. To solve my issue for now which is want to pass zone/1 for Get(int id) and optionally passing either none, one or both of typeId & zoneId to return the list, what is my best option? – PMC Aug 04 '12 at 07:21
  • So you meant, you want to pass zoneId for Get(int id) typeId & zoneId for another method? For more clear, your route should be: "api/{controller}/{zoneId}". And your method: Get(int zoneId) – cuongle Aug 04 '12 at 07:34
  • Yes but I think I am getting somewhere using var queryValues = HttpUtility.ParseQueryString(Request.RequestUri.Query); – PMC Aug 04 '12 at 07:37
  • If so, you don't need the second route, just put on the query string – cuongle Aug 04 '12 at 07:42
  • Yes, I've removed this. Thanks for your help, I will update my answer later in the week with my working code. – PMC Aug 04 '12 at 07:48
1

If you want to pass typeId and zoneId as query string parameters, your URIs should be:

/Time?typeId=1

/Time?zoneId=1

... in that case, you don't need typeId and zoneId in the route templates.

On the other hand, if you want them as URI segments (which is what your "TemplateTimeApi" route shows), then your URI should be:

/Time/1/1

With the second option, you would have to include both parameters in the URI to trigger the route, because a URI like "/Time/1" will match the "DefaultApi" route.

Mike Wasson
  • 6,572
  • 2
  • 24
  • 20
  • Thanks Mike, hadn't thought about querystring parameters, didn't know how they were used. By the way, great work with your WebAPI resources online. – PMC Aug 04 '12 at 07:00