Search code examples
asp.netasp.net-core-webapirestful-url

In .net core Restful API how to change URL format to get double parameter with single method name?


With these two formats of URL these codes work fine:

http://localhost:51996/weatherforecast/help/p1
http://localhost:51996/weatherforecast/help/p1/p2

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet("help/{a}")]
    [Route("help")]
   
    public string help( string  a)
    {
        return "single param";
    }

    [HttpGet("help/{b}/{c}")]
    [Route("help")]
    public string help( string b,string c)
    {
        return "double param";
    }
}

But how can I change my routes or anything to work with this type of URL:

http://localhost:51996/weatherforecast/help?a=p1
http://localhost:51996/weatherforecast/help?b=p1&c=p2

Solution

  • You are pulling from query string. So your routes are set up wrong. Try this:

    [HttpGet, Route("help")]
    public string help([FromQuery] string  a)
    {
        return "single param";
    }
    
    [HttpGet, Route("help")]
    public string help([FromQuery]string b, [FromQuery] string c)
    {
        return "double param";
    }
    

    But, the issue here is you have to routes that are identical. By default query strings are optional. So both these could be called the same way, the framework wouldn't know which one to call.

    Example: You could call https://example.com/api/Controller/help, and both these methods are acceptable endpoints for that request.

    So you need a way to differentiate the two.

    Either change the name of the endpoint:

    [HttpGet, Route("helpA")]
    public string helpA([FromQuery] string  a)
    {
        return "single param";
    }
    
    [HttpGet, Route("helpBC")]
    public string helpBC([FromQuery]string b, [FromQuery] string c)
    {
        return "double param";
    }
    
    // https://www.example.com/api/Controller/helpA/?a=string
    // https://www.example.com/api/Controller/helpBC/?b=string1&c=string2
    

    Or, you could change the path and make the strings required:

    [HttpGet, Route("help/{a}")]
    
    public string helpA(string  a)
    {
        return "single param";
    }
    
    [HttpGet, Route("help/{b}/{c}")]
    public string helpBC(string b, string c)
    {
        return "double param";
    }
    
    // https://www.example.com/api/Controller/help/string
    // https://www.example.com/api/Controller/help/string1/string2
    

    Another thing you could do is combine all three, then make sure your documentation explains that they should use one or the other:

    [HttpGet, Route("help")]
    public string helpABC(
        [FromQuery]string a, [FromQuery]string b, [FromQuery]string c)
    {
        if(string.IsNullOrEmpty(a)){
            // b and c must not be null or empty
        }
        // etc...
    }