10

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?

2 Answers 2

9

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) => 
    id == default
        ? symbolService.GetSymbolsAsync()
        : symbolService.GetValidChildrenAsync(id);
Sign up to request clarification or add additional context in comments.

1 Comment

you can use [FromUri] for a complex object.
1
//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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.