Action Results in Web API 2
A Web API controller action can return any of the following:
- void
- HttpResponseMessage
- IHttpActionResult
- Some other type
HttpResponseMessage
public class ValuesController : ApiController
{
public HttpResponseMessage Get()
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
response.Content = new StringContent("hello", Encoding.Unicode);
response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromMinutes(20)
};
return response;
}
}
Response:
HTTP/1.1 200 OK Cache-Control: max-age=1200
Content-Length: 10 Content-Type: text/plain;
charset=utf-16 Server: Microsoft-IIS/8.0 Date: Mon, 27 Jan 2014 08:53:35 GMT
hello
serialized model into the response body.
public HttpResponseMessage Get()
{
// Get a list of products from a database.
IEnumerable<Product> products = GetProductsFromDB();
// Write the list to the response body.
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, products);
return response;
}
Other Return Types
public class ProductsController : ApiController
{
public IEnumerable<Product> Get()
{
return GetAllProductsFromDB();
}
}
Example response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Mon, 27 Jan 2014 08:53:35 GMT
Content-Length: 56
[{"Id":1,"Name":"Yo-yo","Category":"Toys","Price":6.95}]
Routing Tables
WebApiConfig.cs
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Routing Variations
- [HttpGet]
- [HttpPut]
- [HttpPost]
- [HttpDelete]
- [HttpHead]
- [HttpOptions]
- [HttpPatch]
Routing by Action Name
configure:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
controller
public class ProductsController : ApiController
{
[HttpGet]
public string Details(int id);
}
public class ProductsController : ApiController
{
[HttpGet]
[ActionName("Thumbnail")]
public HttpResponseMessage GetThumbnailImage(int id);
[HttpPost]
[ActionName("Thumbnail")]
public void AddThumbnailImage(int id);
}
With attribute routing
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
Enabling Attribute Routing
using System.Web.Http;
namespace WebApplication
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Adding Route Attributes
public class OrdersController : ApiController
{
[Route("customers/{customerId}/orders")]
[HttpGet]
public IEnumerable<Order> FindOrdersByCustomer(int customerId) { ... }
}
T
The following URIs would match this template:
- http://localhost/customers/1/orders
- http://localhost/customers/bob/orders
- http://localhost/customers/1234-5678/orders
A URI template can have several parameters:
[Route("customers/{customerId}/orders/{orderId}")]
public Order GetOrderByCustomer(int customerId, int orderId) { ... }
Optional URI Parameters and Default Values
public class BooksController : ApiController
{
[Route("api/books/locale/{lcid:int?}")]
public IEnumerable<Book> GetBooksByLocale(int lcid = 1033) { ... }
}
In this example, /api/books/locale/1033 and /api/books/locale return the same resource.
Alternatively, you can specify a default value inside the route template, as follows:
public class BooksController : ApiController
{
[Route("api/books/locale/{lcid:int=1033}")]
public IEnumerable<Book> GetBooksByLocale(int lcid) { ... }
}
Route Names
public class BooksController : ApiController
{
[Route("api/books/{id}", Name="GetBookById")]
public BookDto GetBook(int id)
{
// Implementation not shown...
}
[Route("api/books")]
public HttpResponseMessage Post(Book book)
{
// Validate and add book to database (not shown)
var response = Request.CreateResponse(HttpStatusCode.Created);
// Generate a link to the new book and set the Location header in the response.
string uri = Url.Link("GetBookById", new { id = book.BookId });
response.Headers.Location = new Uri(uri);
return response;
}
}
Route Order
[RoutePrefix("orders")]
public class OrdersController : ApiController
{
[Route("{id:int}")] // constrained parameter
public HttpResponseMessage Get(int id) { ... }
[Route("details")] // literal
public HttpResponseMessage GetDetails() { ... }
[Route("pending", RouteOrder = 1)]
public HttpResponseMessage GetPending() { ... }
[Route("{customerName}")] // unconstrained parameter
public HttpResponseMessage GetByCustomer(string customerName) { ... }
[Route("{*date:datetime}")] // wildcard
public HttpResponseMessage Get(DateTime date) { ... }
}
REST API for a collection of books
Example | URI |
---|---|
Get a list of all books. | /api/books |
Get a book by ID. | /api/books/1 |
Get the details of a book. | /api/books/1/details |
Get a list of books by genre. | /api/books/fantasy |
Get a list of books by publication date. | /api/books/date/2013-02-16 /api/books/date/2013/02/16 (alternate form) |
Get a list of books by a particular author. | /api/authors/1/books |