What's New in ASP.NET Web API 2.1

by Microsoft

This topic describes what's new for ASP.NET Web API 2.1.

Download

The runtime features are released as NuGet packages on the NuGet gallery. All the runtime packages follow the Semantic Versioning specification. The latest ASP.NET Web API 2.1 RTM package has the following version: "5.1.2". You can install or update these packages through NuGet. The release also includes corresponding localized packages on NuGet.

You can install or update to the released NuGet packages by using the NuGet Package Manager Console:

Install-Package Microsoft.AspNet.WebApi -Version 5.1.2

Documentation

Tutorials and other information about ASP.NET Web API 2.1 RTM are available from the ASP.NET web site (https://www.asp.net/web-api).

New Features in ASP.NET Web API 2.1

Global Error Handling

All unhandled exceptions can now be logged through one central mechanism, and the behavior for unhandled exceptions can be customized.

The framework supports multiple exception loggers, which all see the unhandled exception and information about the context in which it occurred, such as the request being processed at the time.

For example, the following code uses System.Diagnostics.TraceSource to log all unhandled exceptions:

public class TraceSourceExceptionLogger : ExceptionLogger
{
    private readonly TraceSource _traceSource;

    public TraceSourceExceptionLogger(TraceSource traceSource)
    {
        _traceSource = traceSource;
    }

    public override void Log(ExceptionLoggerContext context)
    {
        _traceSource.TraceEvent(TraceEventType.Error, 1,
            "Unhandled exception processing {0} for {1}: {2}",
            context.Request.Method,
            context.Request.RequestUri,
            context.Exception);
    }
}

config.Services.Add(typeof(IExceptionLogger), 
    new TraceSourceExceptionLogger(new 
    TraceSource("MyTraceSource", SourceLevels.All)));

You can also replace the default exception handler, so that you can fully customize the HTTP response message that is sent when an unhandled exception occurs.

We have provided a sample that logs all unhandled exceptions via the popular ELMAH framework.

Attribute Routing Improvements

Attribute routing now supports constraints, enabling versioning and header-based route selection. Also, many aspects of attribute routes are now customizable via the IDirectRouteFactory interface and RouteFactoryAttribute class. The route prefix is now extensible via the IRoutePrefix interface and RoutePrefixAttribute class.

We have provided a sample that uses constraints to dynamically filter controllers by an 'api-version' HTTP header.

Help Page Improvements

Web API 2.1 includes the following enhancements to API Help Pages:

  • Documentation of individual properties of parameters or return types of actions.
  • Documentation of data model annotations.

The UI design of the help pages was also updated, to accommodate these changes.

IgnoreRoute Support

Web API 2.1 supports ignoring URL patterns in Web API routing, through a set of IgnoreRoute extension methods on HttpRouteCollection. These methods cause Web API to ignore any URLs that match a specified template, and allow the host to apply additional processing if appropriate.

The following example ignores URIs that start with a "content" segment:

routes.IgnoreRoute("IgnoreContent", "content/{*paths}");
routes.MapHttpRoute("Default", "{controller}/{id}");

BSON Media-Type Formatter

Web API now supports the BSON wire format, both on the client and on the server.

To enable BSON on the server side, add the BsonMediaTypeFormatter to the formatters collection:

config.Formatters.Add(new BsonMediaTypeFormatter());

Here is how a .NET client can consume BSON format:

// Add Accept header.
client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/bson"));

// POST data in BSON format.
HttpResponseMessage response = await client.PostAsync<MyData>("api/MyData", data, new 
BsonMediaTypeFormatter());

// GET data in BSON format.
data = await response.Content.ReadAsAsync<MyData>(new MediaTypeFormatter[] { 
  new BsonMediaTypeFormatter() });

We have provided a sample that shows both the client and server side.

For more information, see BSON Support in Web API 2.1

Better Support for Async Filters

Web API now supports an easy way to create filters that execute asynchronously. This feature is useful is your filter needs to perform an async action, such as access a database. Previously, to create an async filter, you had to implement the filter interface yourself, because the filter base classes only exposed synchronous methods. Now you can override the virtual On*Async methods of the filter base class.

For example:

public class AsyncLoggingFilter : ActionFilterAttribute
{
    public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        await Trace.WriteAsync("Executing action named {0} for request {1}.", 
            actionContext.ActionDescriptor.ActionName, 
            actionContext.Request.GetCorrelationId());
    }
}

The AuthorizationFilterAttribute, ActionFilterAttribute, and ExceptionFilterAttribute classes all support async in Web API 2.1.

Query Parsing for the Client Formatting Library

Previously, System.Net.Http.Formatting supported parsing and updating URI queries for server-side code, but the equivalent portable library was missing this feature. In Web API 2.1, a client application can now easily parse and update a query string.

The following examples show how to parse, modify, and generate URI queries. (The examples show a console application for simplicity.)

// Query parsing
HttpValueCollection collection = new Uri("http://api/something?catId=3&catId=4&dogId=1,2").ParseQueryString();

Console.WriteLine(collection["catId"]); // output: 3,4
Console.WriteLine(collection["dogId"]); // output: 1,2

// Modify the query
collection.Add("dogId", "7");

// Index into the values
Console.WriteLine(collection["catId"]); // output: 3,4
Console.WriteLine(collection["dogId"]); // output: 1,2,7

// Recreate the query string
Console.WriteLine(collection.ToString()); // output: catId=3&catId=4&dogId=1%2C2&dogId=7

// Query generation
HttpValueCollection newCollection = new HttpValueCollection();

newCollection.Add("catId", "1");
newCollection.Add("dogId", "7");

// Index into the values
Console.WriteLine(newCollection["catId"]); // output: 1
Console.WriteLine(newCollection["dogId"]); // output: 7

// Create the query string
Console.WriteLine(newCollection.ToString()); // catId=1&dogId=7

Known Issues and Breaking Changes

This section describes known issues and breaking changes in the ASP.NET Web API 2.1 RTM.

Attribute Routing

Ambiguities in attribute routing matches now report an error rather than choosing the first match.

Attribute routes are prohibited from using the {controller} parameter, and from using the {action} parameter on routes placed on actions. These parameters would very likely cause ambiguities.

Scaffolding MVC/Web API into a project with 5.1 packages results in 5.0 packages for ones that don't already exist in the project

Updating NuGet packages for ASP.NET Web API 2.1 RTM does not update the Visual Studio tools, such as ASP.NET scaffolding or the ASP.NET Web Application project template. They use the previous version of the ASP.NET runtime packages (5.0.0.0). As a result, the ASP.NET scaffolding will install the previous version (5.0.0.0) of the required packages, if they are not already available in your projects. However, the ASP.NET scaffolding in Visual Studio 2013 RTM or Update 1 does not overwrite the latest packages in your projects.

If you use ASP.NET scaffolding after updating the packages to Web API 2.1 or ASP.NET MVC 5.1, make sure the versions of Web API and MVC are consistent.

Type Renames

Some of the types used for attribute routing extensibility were renamed from the RC to the 2.1 RTM.

Old type name (2.1 RC) New Type Name (2.1 RTM)
IDirectRouteProvider IDirectRouteFactory
RouteProviderAttribute RouteFactoryAttribute
DirectRouteProviderContext DirectRouteFactoryContext

Exception filters do not unwrap aggregate exceptions thrown in async actions

Previously, if an async action threw an AggregateException, an exception filter would unwrap the exception, and OnException would get the base exception. In 2.1, the exception filter does not unwrap it, and OnException gets the original AggregateException.

Bug Fixes

This release also includes several bug fixes.

The 5.1.2 package contains IntelliSense updates but no bug fixes.