Web API 2 Controller with multiple GET methods - part 2

I have two other posts on multiple GET methods, one for ASP.NET 5 Web Api, and another for Web Api 2.

Download full source code.

A few months ago I wrote a post explaining how to create a controller with multiple GET methods. In that I used the combination of [RoutePrefix..] and [Route...] to generate routes like

- http://.../api/values/geta
- http://.../api/values/getb

Attribute parameter names and type

In this post I will show a different way of achieving multiple GETs by matching the type of parameter passed to the controller with the appropriate method.

In the first example I will match a method to an int being passed in, note the [Route("{id:int}")], this specifies that the expected parameter is named “id” and is an int.

1// GET api/values/7
2[Route("{id:int}")]
3public string Get(int id)
4{
5    return $"You entered an int - {id}";
6}

It is no problem to add another GET method with a [Route("{id:Guid}")]. This works fine because there is no way and int and Guid can be confused.

1// GET api/values/AAC1FB7B-978B-4C39-A90D-271A031BFE5D
2[Route("{id:Guid}")]
3public string Get(Guid id)
4{
5    return $"You entered a GUID - {id}";
6}

Where we start having problems is when the attribute routing system can’t determine which method you were attempting to call because it can’t distinguish an int from a long (or a string, decimal etc.)

For example, if we had another GET method taking a long, it would cause many runtime errors.

1// GET api/values/8 - this will not work because it could be an int or a long
2// GET api/values/4147483647 - this works because it can ONLY be a long
3[Route("{id:long}")]
4public string Get(long id)
5{
6    return $"You entered an long - {id}";
7}

If we called http://...api/values/8, the attribute routing system has no way of knowing whether the GET method for the int or the long should be called.

But if we called http://...api/values/4147483647, that number is larger than an int can hold, the attribute routing system knows only one method matches the call.

If you want to have longs and ints in the same controller one of the routes needs to be altered. Note the new route - [Route("large/{id:long}")].

To call it now use http://...api/values/large/8 or http://...api/values/large/4147483647

1[Route("large/{id:long}")]
2public string Get(long id)
3{
4    return $"You entered an long - {id}";
5}

Download full source code.

comments powered by Disqus

Related