Greg
Greg

Reputation: 8784

Asp.Net Web API Routing - Required QueryString Parameters

How can I require a querystring for certain routes in an Asp.Net Web API?

Controllers:

public class AppleController : ApiController
{
    public string Get() { return "hello"; }
    public string GetString(string x) { return "hello " + x; }
}

public class BananaController : ApiController
{
    public string Get() { return "goodbye"; }
    public string GetInt(int y) { return "goodbye number " + y; }
}

Desired routes:

/apple        --> AppleController  --> Get()
/apple?x=foo  --> AppleController  --> Get(x)
/banana       --> BananaController --> Get()
/banana?y=123 --> BananaController --> Get(y)

Upvotes: 3

Views: 4653

Answers (3)

Matthieu
Matthieu

Reputation: 826

I had a similar question this morning, and I think I found a simpler way to configure my routes. In your case, use this:

config.Routes.MapHttpRoute(
    name: "AppleRoute",
    routeTemplate: "apple",
    defaults: new { controller = "Apple" }
);

config.Routes.MapHttpRoute(
    name: "BananaRoute",
    routeTemplate: "banana",
    defaults: new { controller = "Banana" }
);

Just specify the controller, and let the framework select the correct action, based on whether your query string parameter is present or not.

Upvotes: 0

naspinski
naspinski

Reputation: 34717

Just do something like this:

public string Get(int y = -1)
{ 
    if(y < 0) return "goodbye"; 
    return "goodbye number " + y; 
}

That way it is one route, and covers all cases. You could factor each out as private methods as well for clarity.

Another method would be to add more routes, but since these are somewhat specific, you would have to add extra routes. For simplicity, I would say you change the methods GetString and GetInt to the same thing (like GetFromId so you can reuse a route:

routes.MapRoute(
    name: "GetFromIdRoutes",
    url: "{controller}/{id}",
    defaults: new { action = "GetFromId" }
);

routes.MapRoute(
    name: "GetRoutes",
    url: "{controller}",
    defaults: new { action = "Get" }
);

If you do not make these general enough, you could end up with a LOT of route entries. Another idea would be to put these into Areas to avoid route confilcts.

Upvotes: 3

user1477388
user1477388

Reputation: 21440

You can specify a query string in your route as either optional or non (in Global.asax):

    ' MapRoute takes the following parameters, in order:
    ' (1) Pages
    ' (2) ID of page
    ' (3) Title of page
    routes.MapRoute( _
        "Pages", _
        "Pages/{id}/{title}", _
        New With {.controller = "Home", .action = "Pages", .id = UrlParameter.Optional, .title = UrlParameter.Optional} _
    )

This is VB.NET.

Upvotes: 0

Related Questions