简体   繁体   中英

Web Api Attribute Routing with optional parameters and query parameters

I have this web api controller :

[RoutePrefix("api/product")]
public class ProductController : ApiController
{
    [HttpGet, Route("{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] string param1 = null, [FromUri] string param2 = null, Guid? id = null)
    {
        ...     
    }
}

I would like to access by those uri :
api/product/?param1=something&param2=smt
or
api/product/7b55fcee-21e7-4b10-80e3-42b4d9cf913d?param1=something&param2=smt

However, the first uri does not work, default value for route parameter is not set.
This uri works :
api/product/null?param1=something&param2=smt
not this one :
api/product/?param1=something&param2=smt

I tried to use the type "string" for the route parameter but it still didn't work.

Is it the order of parameters ?
Or did I misunderstood something about Web Api Route Mapping ?

EDIT : My WebApiConfig.cs does not contains default routes :

public static class EdmWebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
       if (config == null) throw new ArgumentNullException(nameof(config));

       // Attribute routing
       config.MapHttpAttributeRoutes();

       ...
       some declaration of formatters
       ...
    }
}

Should I declare a default route ?
In my opinion, since I use Attribute mapping, I don't need to do that.

I tried to change my routing like that :

[RoutePrefix("api")]
public class ProductController : ApiController
{

    [HttpGet, Route("product/get/{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] Guid param1, [FromUri] string param2, Guid? id = null)
    {
      ...
    }
}

This uri api/product/get/?param1=something&param2=smt still does not work.
(I tried api/product/?param1=something&param2=smt with the associated routing, not working)

Do I need to declare default route in my WebApiConfig.cs ?
What you can do in WebApiConfig.cs, you should be able to do it in attribute routing, isn't it ? Like optional parameters, constrainsts,...

Your route prefix is too specific. I believe you want:

[RoutePrefix("api")]
public class ProductController : ApiController
{
    [HttpGet, Route("product/{id?}")]
    public async Task<HttpResponseMessage> GetProduct([FromUri] string param1 = null, [FromUri] string param2 = null, Guid? id = null)
    {
        ...     
    }
}

Which should work well for you. A route prefix is not a route in-and-of itself, so the default route should be less specific.

I can't reconstruct this error but I'd like to recommend a better pattern for you to follow.

You have a single method which is too general and needs major examination of the parameters prior to do the actual job.

That would be nicer if you to have two separate endpoints. A general Get method like:

Get([FromUri] string keyword = null)

And another one such as:

GetById(Guid id)

The way you have set your RoutePrefix is correct and you don't need to change it.

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