ASP.NET Web API: CORS support and Attribute Based Routing Improvements
We’ve seen a huge adoption of ASP.NET Web API since its initial release. In February we shipped the ASP.NET and Web Tools 2012.2 Update – which added a number of additional enhancements to both Web API and the other components of ASP.NET.
The ASP.NET Team has been hard at work on developing the next set of features (lots of cool stuff coming). One of the great things about this work has been how the team has used the open source development process – which we announced we were adopting last spring - to collaborate even more closely with the community to both validate the features early, as well as enable developers in the community to directly contribute to the development of them.
Below are some updates on two of the great features coming to ASP.NET Web API – which were developed and contributed by ASP.NET MVP Brock Allen and Tim McCall (of attributerouting.net fame):
CORS support for ASP.NET Web API
Cross-origin resource sharing (CORS) is a W3C standard that allows web pages to make AJAX requests to a different domain. This standard relaxes the same-origin policy implemented in web browsers that restricts calls to the domain of the resource that makes the call. The CORS specification defines how the browser and server interact to make cross-origin calls.
The following image shows the ASP.NET Web API Test Tool (running on http://xyz123.azurewebsites.net/) making a cross domain call to the Contoso domain. When you click Send, a cross-origin request is made. Because the Contoso site is not configured to support CORS, an error dialog is displayed.
The CORS error appears on the Console tab of the IE F12 tools.
For security reasons, the web browser doesn’t allow calls from the azurewebsites domain to the Contoso domain. With the new ASP.NET Web API CORS framework, Contoso.com can be configured to send the correct CORS headers so the browser will accept cross-origin calls.
MVP Brock Allen contributed his CORS source to the ASP.NET Webstack repository. Brock worked with Yao Huang Lin (a developer on the ASP.NET team), to refine and iterate the design and then to get it pulled into the Webstack repository. Brock Allen, Dan Roth, and Yao discuss Brock’s CORS contribution in this Channel 9 video.
The CORS support for ASP.NET Web API page shows how to get started with this new feature.
Attribute-Based Routing in ASP.NET Web API
We recently published in the ASP.NET Web API roadmap our intention to support attribute- based routing in ASP.NET Web API. Route attributes bring the URL definition closer to the code that runs for that particular URL, making it easier to understand which URL must be called for a particular block of code and simplifying many common routing scenarios.
For example, let’s say you want to define a Web API that has the standard set of HTTP actions (GET, POST, PUT, DELETE, and so on) but you also want to have an additional custom action, such as Approve. Instead of adding another route to the global route table for the Approve action, you can instead just attribute the action directly:
public class OrdersController : ApiController
{
public IEnumerable<Order> GetOrders() {…}
public Order GetOrder(int id) {…}
public Order Post(Order order) {…}
[HttpPost("orders/{id}/approve")]
public Order Approve(int id) {…}
}
An extended route template syntax makes it simple to specify default values and constraints for route values. For example, you can now easily create two actions that are called based on parameter type. In the following People controller, the id parameter of the GetByID action takes only int values. The GetByName action method contains a default name of “Nick”.
public class PeopleController : ApiController
{
[HttpGet("{name=Nick}")]
public string GetByName(string name) {…}
[HttpGet("{id:int}")]
public string GetById(int id) {…}
}
You can also define common route prefixes for your web APIs. For example, you can use route prefixes to set up a resource hierarchy:
[RoutePrefix("movies")]
[RoutePrefix("actors/{actorId}/movies")]
[RoutePrefix("directors/{directorId}/movies")]
public class MoviesController : ApiController
{
public IEnumerable<Movie> GetMovies() {…}
public IEnumerable<Movie> GetMoviesByActor(int actorId) {…}
public IEnumerable<Movie> GetMoviesByDirector(int directorId) {…}
}
Or, you can use route prefixes to handle multiple versions of your web API:
[RoutePrefix("api/v1/customers")]
public class CustomersV1Controller : ApiController {…}
[RoutePrefix("api/v2/customers")]
public class CustomersV2Controller : ApiController {…}
Similar to the new CORS support in ASP.NET Web API, the new support for attribute-based routing is largely a contribution from the community. We are working closely with Tim McCall of attributerouting.net fame to bring many of the features of his AttributeRouting project directly into ASP.NET Web API.
It’s really exciting to see how these collaborations across the ASP.NET Team and the community are helping to move the ASP.NET platform forward!
Hope this helps,
Scott
P.S. In addition to blogging, I use Twitter to-do quick posts and share links. My Twitter handle is: @scottgu