Query string not working while using attribute routing

Chris Paton picture Chris Paton · Mar 25, 2014 · Viewed 82.2k times · Source

I'm using System.Web.Http.RouteAttribute and System.Web.Http.RoutePrefixAttribute to enable cleaner URLs for my Web API 2 application. For most of my requests, I can use routing (eg. Controller/param1/param2) or I can use query strings (eg. Controller?param1=bob&param2=mary).

Unfortunately, with one of my Controllers (and only one), this fails. Here is my Controller:

[RoutePrefix("1/Names")]
public class NamesController : ApiController
{

    [HttpGet]
    [Route("{name}/{sport}/{drink}")]
    public List<int> Get(string name, string sport, string drink)
    {
        // Code removed...
    }

    [HttpGet]
    [Route("{name}/{drink}")]
    public List<int> Get(string name, string drink)
    {
        // Code removed...
    }
}

When I make a request to either using routing, both work fine. However, if I use a query string, it fails, telling me that that path does not exist.

I have tried adding the following to my WebApiConfig.cs class' Register(HttpConfiguration config) function (before and after the Default route), but it did nothing:

config.Routes.MapHttpRoute(
name: "NameRoute",
routeTemplate: "{verId}/Names/{name}/{sport}/{drink}",
defaults: new { name = RouteParameter.Optional, sport = RouteParameter.Optional, drink = RouteParameter.Optional },
constraints: new { verId = @"\d+" });

So for clarity, I would like to be able to do both this:

localhost:12345/1/Names/Ted/rugby/coke
localhost:12345/1/Names/Ted/coke

and,

localhost:12345/1/Names?name=Ted&sport=rugby&drink=coke
localhost:12345/1/Names?name=Ted&drink=coke

but sadly the query string versions don't work! :(

Updated

I've removed the second Action altogether and now trying to use just a singular Action with optional parameters. I've changed my route attribute to [Route("{name}/{drink}/{sport?}")] as Tony suggested to make sport nullable, but this now prevents localhost:12345/1/Names/Ted/coke from being a valid route for some reason. Query strings are behaving the same way as before.

Update 2 I now have a singular action in my controller:

[RoutePrefix("1/Names")]
public class NamesController : ApiController
{

    [HttpGet]
    [Route("{name}/{drink}/{sport?}")]
    public List<int> Get(string name, string drink, string sport = "")
    {
        // Code removed...
    }
}

but still, using query strings does not find a suitable path, while using the routing method does.

Answer

Mosharaf Hossain picture Mosharaf Hossain · Nov 3, 2015

I was facing the same issue of 'How to include search parameters as a query string?', while I was trying to build a web api for my current project. After googling, the following is working fine for me:

Api controller action:

[HttpGet, Route("search/{categoryid=categoryid}/{ordercode=ordercode}")]

public Task<IHttpActionResult> GetProducts(string categoryId, string orderCode)
{

}

The url I tried through postman:

http://localhost/PD/search?categoryid=all-products&ordercode=star-1932

http://localhost/PD is my hosted api