20

I remember from ASP.NET Web API that it's sufficient to prefix Web API REST method names with HTTP commands (e.g. GetList() => HTTP GET, Delete() => HTTP DELETE) to have incoming calls appropriately routed.

I also remember that in ASP.NET Web API parameter matching takes place so that even Get(int id) and Get(int id, string name) get automatically and appropriately routed without requiring any attributes.

public class MyController
{
  public ActionResult Get(int id) => ...

  public ActionResult Get(int id, string name) => ...

  public ActionResult DeleteItem(int id) => ...
}

Isn't this all available in ASP.NET Web API Core?

1
  • 1
    Is this code complete? i think you forgot to inherit from ControllerBase
    – Leonardo
    Commented Jun 12, 2019 at 14:51

4 Answers 4

49

You just need to add the Route to the top of your controller.

Specify the route with api, controller and action:

[Route("api/[controller]/[action]")]
[ApiController]
public class AvailableRoomsController : ControllerBase
{
...
}
1
  • 6
    Note: api is optional, but seems to be the general convention to denote an api url. Commented Jun 12, 2019 at 16:51
2

Neither could we do action overloads nor prefix action name as Http verb.The way routing works in ASP.NET Core is different than how it did in ASP.NET Web Api.

However, you can simply combine these actions and then branch inside, since all params are optional if you send as querystring

[HttpGet]
public ActionResult<string> Get(int id, string name)
{
  if(name == null){..}
  else{...}
}

Or you need to use attribute routing to specify each api if you send in route data:

[HttpGet("{id}")]       
public ActionResult<string> Get(int id)
{
    return "value";
}


[HttpGet("{id}/{name}")]
public ActionResult<string> Get(int id, string name)
{
    return name;
}

Refer to Attribute Routing,Web Api Core 2 distinguishing GETs

1

The aspnetcore webapi controllers do not natively support inference of http verbs by naming convention, but allow you to create your own convention and achieve this behavior.

Create your convention

public class MyConvention : IApplicationModelConvention
{
    public void Apply(ApplicationModel application)
    {
        foreach(var controller in application.Controllers)
        {
            foreach(var action in controller.Actions)
            {
                if (action.ActionName.StartsWith("Post"))
                {
                    action.Selectors.First().ActionConstraints.Add(new HttpMethodActionConstraint(new[]{ "POST" }));
                }
            }
        }
    }
}

Then register it in Program/Startup:

builder.Services.AddControllers(configure => configure.Conventions.Insert(0, new MyConvention()));
0

This is available for Core 2 yes, but the way that I know how to do it is something like this

[Route("api/[controller]")]
[ApiController]
public class AvailableRoomsController : ControllerBase
{
    private readonly ApplicationContext _context;

    public AvailableRoomsController(ApplicationContext context)
    {
        _context = context;
    }

    // GET: api/AvailableRooms
    [HttpGet]
    public async Task<ActionResult<IEnumerable<AvailableRoom>>> GetAvailableRooms()
    {
        return await _context.AvailableRooms.ToListAsync();
    }


    // POST: api/AvailableRooms
    [HttpPost]
    public async Task<ActionResult<AvailableRoom>> PostAvailableRoom(AvailableRoom availableRoom)
    {
        _context.AvailableRooms.Add(availableRoom);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetAvailableRoom", new { id = availableRoom.Id }, availableRoom);
    }

    [HttpPut] .... etc
}

Now depending on what kind of REST action you specify and what type of model you send to "api/AvailableRooms" if the proper Action exists it will be chosen.

Visual Studio 2019 and I think 2017 can create a controller such as this automatically if you right click your Controllers folder and click Add->Controller and then choose "API Controller with actions, using Entity Framework" and choose one of your Model classes.

3
  • This will have issues when doing multiple Get's / Post's in the same controller. The routing will get confused. Commented Jun 12, 2019 at 16:48
  • I should say the routing can get confused - if there are different calls with similar parameters and method types (EX: 2 gets that take the same parameter). Commented Jun 12, 2019 at 16:58
  • That is true, this type of controllers are designed for CRUD operations, supposed to handle one the 5 actions tied to the Model, that would be Get Post Put Delete and Get with ID. I usually use them in combination with some Data Table framework and have an API controller decorated with [Route("api/[action]")] for more complex calls.
    – Elias K.
    Commented Jun 12, 2019 at 17:50

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.