Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I need to make a ASP.NET Core, Web API that supports multiple HttpGet verbs with the only difference being a query string, but it seems that query strings cannot be part of the route template -- is that true?

The route templates are very similar, in fact they only differ by query string.

[Authorize]
public class SymbolsController : Controller
{
    [
        HttpGet, 
        Route("api/symbols")
    ]
    public Task<IEnumerable<Symbol>> Symbols([FromServices] ISymbolService symbolService)
    {
        return symbolService.GetSymbolsAsync();
    }

    [
        HttpGet, 
        Route("api/symbols?{childrenOf=id}")
    ]
    public Task<IEnumerable<Symbol>> ValidChildren(
        [FromQuery] Guid id, 
        [FromServices] ISymbolService symbolService)
    {
        return symbolService.GetValidChildrenAsync(id);
    }
}

This throws an exception as the ? is not a valid character in the route template. How can I achieve this?

share|improve this question
up vote 2 down vote accepted

I figured out an easier and more straightforward solution. I am simply using the FromQuery attribute and leaving the template simple. I check for the presence of the id variable and handle it accordingly.

[HttpGet, Route("api/symbols")]
public Task<IEnumerable<Symbol>> Symbols(
    [FromQuery] Guid id, 
    [FromServices] ISymbolService symbolService)
{
    return id == default(Guid)
              ? symbolService.GetSymbolsAsync()
              : symbolService.GetValidChildrenAsync(id);
}
share|improve this answer
    
you can use [FromUri] for a complex object. – nld Aug 16 at 22:21

Query parameters are essentially not a part in the route when you define it with attribute routing. More details would be here I think.

If you opt not to use attribute routing and want to define a route you can opt for a the Routing Middleware here.

You can opt for a lot of other ways too described in the following links. Although a lot of them are from web api 2 or MVC4, it should work almost the same in Asp.net Core too.

But the best thing to do here would be mapping an http route. Quoting from the official doc:

routes.MapRoute(
   name: "default_route",
   template: "{controller=Home}/{action=Index};

And then you can have two Index actions with separate query params

Index(string name)
{
   // Your code here 
}

Index(string type)
{
   // Your code here 
}
  1. ASP.NET WebApi - Multiple GET actions in one controller
  2. Single controller with multiple GET methods in ASP.NET Web API
share|improve this answer
//eg GET api/symbols
//eg GET api/symbols?childrenOf={someGuid}
[HttpGet("api/symbols")]
public Task<IEnumerable<Symbol>> Symbols(
    [FromServices] ISymbolService symbolService, 
    Guid? childrenOf = null)
{
    if (childredOf.HasValue) {
        return ValidChildren(childredOf.Value, symbolService);
    }
    return symbolService.GetSymbolsAsync();
}

Task<IEnumerable<Symbol>> ValidChildren(
    Guid id, 
    ISymbolService symbolService)
{
    return symbolService.GetValidChildrenAsync(id);
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.