`RouteAttribute` declares a controller’s base URL in ASP.NET Core MVC. Put `[Route("api/[controller]")]` on `ProductsController`: the `[controller]` token drops the `Controller` suffix, producing `/api/products`. section 19.4.2
Action attributes combine an HTTP method with that base URL. `[HttpGet]` matches GET `/api/products`; `[HttpGet("{id}")]` matches GET `/api/products/{id}`. For web-service controllers, these attributes and route patterns—not action method names—determine which requests actions handle. section 19.4.2
Listing 19.6 The contents of the ProductsController.cs file in the Controllers folder
using Microsoft.AspNetCore.Mvc;
using WebApp.Models;
namespace WebApp.Controllers {
[Route("api/[controller]")]
public class ProductsController : ControllerBase {
[HttpGet]
public IEnumerable<Product> GetProducts() {
return new Product[] {
new Product() { Name = "Product #1" },
new Product() { Name = "Product #2" },
};
}
[HttpGet("{id}")]
public Product GetProduct() {
return new Product() {
ProductId = 1, Name = "Test Product"
};
}
}
}
The controller listing shows the class-level route alongside both GET actions. section 19.4.2


