ASP.NET Web API Routing and Actions Notes
(Note: Here we only provide a learning note, so most sample code below are not ours, for example, most of them were copied from Microsoft ASP.NET website)
1: Similar to MVC routing, ASP.NET Web API uses routing too.
MVC 5 routing:
In the file App_Start/RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
ASP.NET Web API routing:
In WebAPIConfig.cs file:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
The main difference is that Web API uses the HTTP method, not the URI path, to select the action. You can also use MVC-style routing in Web API.
2: Routing Table:
There is not only one routing can be used in a project, so we have multiple routings and called them routing table.
Each entry in the routing table contains a route template. The default route template for Web API is "api//". In this template, "api" is a literal path segment, and and are placeholder variables.
3: If use default Web API routing, then we must use naming convention for HTTP methods with GET, POST, PUT and DELETE.
for example: We must use:
GetAllProducts to match the URI Path api/products (HTTP Method: GET);
GetProductByID to match the URI api/products/4 (HTTP Method: GET);;
DeleteProduct to match api/products/4 (HTTP Method: DELETE);
If we do not want to be forced to use naming convention for HTTP methods, we can explicitly specify the HTTP method for an action with attributes: HttpGet, HttpPut, HttpPost, HttpDelete:
public class ProductsController : ApiController
{
[HttpGet]
public Product FindProduct(id) {}
}
AcceptVerbs attribute can take a list of HTTP methods including other methods other than Get, Put, Post and Delete.
public class ProductsController : ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id) { }
// WebDAV method
[AcceptVerbs("MKCOL")]
public void MakeCollection() { }
}
4: If self-host Web API, then no WebApiConfig.cs file, we must set the routing table directly on the HttpSelfHostConfiguration object;
5: Routing By Action Name:
We set the routing as this:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Then with this routing, we can specify which one action method we like in Controller as HTTP method using Http attributes, for example:
public class DevicesController : ApiController
{
[HttpGet]
[ActionName("DeviceValue")]
public double GenerateDeviceValue(int id);
}
Non-Actions:
Use [NonAction] attribute to prevent a public method from getting invoked as an action.
6: To provide your own implementation for any of these interfaces, use the Services collection on the HttpConfiguration object:
var config = GlobalConfiguration.Configuration;
config.Services.Replace(typeof(IHttpControllerSelector), new MyControllerSelector(config));
7: constraints:
new { id = @"\d+" } // Only matches if "id" is one or more digits.
see here.
8: ASP.NET Web API released 2 versions by now: ASP.NET Web API and ASP.NET Web API 2; Web API 2 supports new Attribute Routing and earlier style of routing called Convention-Based Routing, Web API only supports Convention-Based Routing;
9: Combine attribute routing with convention-based routing:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// �> enable attribute routing
config.MapHttpAttributeRoutes();
// �> earlier style routing
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
10: Sample of attribute routing:
RoutePrefix("api/books")] // <� route prefix
public class BooksController : ApiController
{
// GET api/books
[Route("")]
public IEnumerable<Book> Get() { � }
// GET api/books/5
[Route("{id:int}")]
public Book Get(int id) { � }
// POST api/books
[Route("")]
public HttpResponseMessage Post(Book book) { � }
// Use a tilde (~) on the method attribute to override the route prefix:
// GET /api/authors/1/books
[Route("~/api/authors/{authorId:int}/books")]
public IEnumerable<Book> GetByAuthor(int authorId) { � }
}