Reputation: 16695
I have the following WebAPI controller:
namespace MyApp.WebApi.Controllers
{
[RoutePrefix("api/listing")]
public class ListingController : ApiController
{
[Route("{firstparam:int?}/{nextparam:int?}")]
public IEnumerable<ListItem> Get(int firstparam = 100, int nextparam = 12)
{
// firstparam is always 100, and nextparam is always 12
However, I've tried specifying the URL:
http://localhost:56004/#/listing?firstparam=2
If I specify the URL like this:
http://localhost:56004/#/listing/2
Then it breaks the routing.
Clearly I'm missing something regarding routing; please could someone point me in the right direction?
Upvotes: 2
Views: 2285
Reputation: 247098
You are using multiple optional parameter which don't work well for routeTemplates. Normally the last parameter tends to be the optional parameter.
Documentation: Attribute Routing in ASP.NET Web API 2: Optional URI Parameters and Default Values
FIrst make sure the attribute routing is enabled
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
To get what you are after
[RoutePrefix("api/listing")]
public class ListingController : ApiController {
//GET api/listing
//GET api/listing?firstparam=x
//GET api/listing?nextparam=y
//GET api/listing?firstparam=x&nextparam=y
[HttpGet]
[Route("")]
public IEnumerable<ListItem> Get(int firstparam = 100, int nextparam = 12) { ... }
}
The problem with having multiple inline parameters that are optional is that the router wont know which to use which is why they tend to be at the end of the url.
However to get them inline like how you mentioned in your example you are going to need multiple routes.
[RoutePrefix("api/listing")]
public class ListingController : ApiController {
//GET api/listing
[HttpGet]
[Route("")]
public IEnumerable<ListItem> Get() { return Get(100, 12); }
//GET api/listing/2
//GET api/listing/2/5
[HttpGet]
[Route("{firstparam:int}/{nextparam:int?}")]
public IEnumerable<ListItem> Get(int firstparam, int nextparam = 12) { ... }
}
Upvotes: 1
Reputation: 38777
You could try using [FromUri] attribute within the params of the Get() method to extract any query params being passed into the "/listing" uri along with a class that consists of int properties firstparam and secondparam.
namespace MyApp.WebApi.Controllers
{
[RoutePrefix("api/listing")]
public class ListingController : ApiController
{
[Route("")]
[HttpGet]
public IEnumerable<ListItem> Get([FromUri] ClassRepresentingParams params)
{
Hopefully that helps.
Upvotes: 0