Tim Gerhard
Tim Gerhard

Reputation: 3607

.Net Core 2.2 Web API Routing

I have the following controller which I wanted to use as an Web API Controller for ajax posts to retrieve data from my user table.

namespace MyProjectName.Controllers.API
{
    [Route("api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
    {
        private readonly myContext _context;
        public UsersController(myContext context)
        {
            _context = context;
        }

        [HttpGet]
        public List<string> GetInstitutionNamesById(int id)
        {
            // returns desired list
        }
    }
}

Now I'd expect the routing of this Function to be like this: /api/users/getinstitutionnamesbyid but apparently it seems to be just /api/users which I find really confusing (what if I add additional HttpGet Functions?).

Can anyone explain me what I am doing wrong? Am I using Web Api Controllers not the Intended way? Is my routing wrong?

Thanks in Advance.

Upvotes: 3

Views: 4400

Answers (2)

Ikram Shah
Ikram Shah

Reputation: 1246

You just need to name it this way

    [HttpGet("[action]/{id}")]
    public List<string> GetInstitutionNamesById(int id)
    {
        // returns desired list
    }

and from ajax call /api/users/GetInstitutionNamesById/1

Upvotes: 2

Kirk Larkin
Kirk Larkin

Reputation: 93113

[Route("api/[controller]")]

With this template, you're explicitly stating that you only care about the name of the controller. In your example, GetInstitutionNamesById is the name of the action, which isn't being considered by the template.

There are a few options for achieving what you're asking for here:

  1. Change your [Route] template to include the action name:

    [Route("api/[controller]/[action]")]
    

    This option applies to all actions within your controller.

  2. Change the HttpGet constraint attribute to specify the action implicitly:

    [HttpGet("[action]")]
    

    This option ensures that the name of your action method will always be used as the route segment.

  3. Change the HttpGet constraint attribute to specify the action explicitly:

    [HttpGet("GetInstitutionNamesById")]
    

    This option allows you to use a route segment that differs from the name of the action method itself.

In terms of whether you're using routing in the correct way here - that's somewhat opinion-based. Generally, you'll see that APIs are attempting to be RESTful, using route templates that match resources, etc. With this approach, you might have something more like the following:

/api/Users/{userId}/InstitutionNames

In this case, you might have a separate InstitutionNames controller or you might bundle it up into the Users controller. There really are many ways to do this, but I won't go into any more on that here as it's a little off-topic and opinion-based.

Upvotes: 13

Related Questions