0
votes

I have below code implemented Web API (.net Framework 4.5.2). When I make a call "http://localhost:3000/123" - It fetches user details whose id is 123. If I make "http://localhost:3000/Class1/?status=Active" - It fetches user details who belong to Class 1 and status as active. Same I converted to .net core and eventhough I mentioned FromQuery, call always goes to ":http://localhost:3000/123"

public class UserController : Controller
{ 
    private Repository repository;

    [HttpGet("{id}")]
    public object Get(string id)
    {
        return repository.GetUser(id) ?? NotFound();
    }

    [HttpGet("{group}")]
    public object Get(string group, Status status)
    {
       // Get the User list from the group and whose status is active
    }
}

Please let me know how to resolve this without changing Route Parameter.

1
Is id always going to be a number? Use a route constraint to differentiate the routesNkosi
id is not a number always. It can be string too.user3197881
I've just had a look at reproducing this issue (I have an idea of how you can make it work), but in my case, it always hits the 2nd method (with the status parameter). Can you just double-confirm that yours is hitting the 1st method?serpent5
It takes based on alphabetical order. Since id comes after group, it's young to group. If I give something as "catalogue" route and "group" route, then, control will go to function with "catalogue" route always.user3197881

1 Answers

0
votes

Simply, you have two conflicting routes here. There's no way for the framework to know which to route to, so it's just going to take the first one. As @Nkosi indicated, if there's some kind of constraint you can put on the param, that will help. You may not be able to restrict to just ints, but perhaps there's a particular regex, for example, that would only match one or the other. You can see your options for constraining route params in the relevant docs.

If there's no clear constraint you can apply that will not also match the other, then you're mostly out of luck here. You can simply change one of the routes to be more explicit, e.g. [HttpGet("group/{group}")]. If the route absolutely must be the same, your only other option is to have one action handle both cases, branching your code depending on some factor.

[HttpGet("{id}")]
public object Get(string id, Status? status = null)
{
   if (status.HasValue)
   {
       // Note: treat `id` as `group` here.
       // Get the User list from the group and whose status is active
   }
   else
   {
       return repository.GetUser(id) ?? NotFound();
   }
}

That may not be the best approach (branching on presence of status), but it's just an example. You'd need to decide what would work best here.