简体   繁体   中英

Web API Routing Not Recognising Parameters

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?

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) { ... }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM