Search code examples
c#asp.net-mvcasp.net-web-apiasp.net-web-api-routingasp.net-mvc-5

Web API 2 / MVC 5 : Attribute Routing passing parameters as querystring to target different actions on same controller


I've been playing with the new Web API 2 (which looks very promising btw) but I'm having a bit of a headache to get some routes working. All works fine when I have GetAllUsers / GetUser(int id), but then when I add GetUserByName(string name) and/or GetUserByUsername(string username) things start to be creepy. I know that the int will be the first one and that I can re-order the routes but let's imagine the following scenario:

A user can have a valid username=1234 or name=1234 (I know it's unlikely but we need to prevent any possible situation) and we might have a valid 1234 ID in the database and all the routes will be mixed up.

Maybe this is something that we will need to work with on the new WebAPI 2 so I thought I could come with an "workaround" passing filters as querystrings to target different action in the same controller, such as api/users/?username=1234 (GetUserByUsername) or api/users/?name=1234 (GetUserByName)

But I cannot make querystrings to come through ... actually any querystring option above is getting caught by the GetAllUsers.

Does anyone have any suggestion/fix for that scenario?

Thanks a lot


Solution

  • You need to define the method access name like

    [HttpGet("User")]
    public async Task<UserViewModel> GetByName(string name)
    [HttpGet("User")]
    public async Task<UserViewModel> GetByUserName(string name)
    
    //You can access like 
    //- api/Users/User?name=someneme
    //- api/Users/User?username=someneme
    

    OR

    [HttpGet("User")]
    public async Task<UserViewModel> GetByAnyName(string name="", string username="")
    //- api/Users/User?name=someneme
    //- api/Users/User?username=someneme
    //- api/Users/User?username=someneme&name=someone
    

    UPDATED Above both will work nicely with other configurations of route prefix.

    OR

    [HttpGet("")]
    public async Task<UserViewModel> GetAll()
    [HttpGet("")]
    public async Task<UserViewModel> Get(int id)
    [HttpGet("")]
    public async Task<UserViewModel> GetByName(string name)
    [HttpGet("")]
    public async Task<UserViewModel> GetByUserName(string name)
    
    //You can access like 
    //- api/Users/
    //- api/Users/?id=123
    //- api/Users/?name=someneme
    //- api/Users/?username=someneme