New in 2.2, there are a few changes in the routing model: Endpoint Routing.

As stated in the post, one of the biggest reasons for this in 2.2 is to improve the performance of routing and MVC’s action selection.

Excited? Yes, why not?

Now, if some of your REST API endpoints are returning HTTP 201 and you are using API versioning (Microsoft.AspNetCore.Mvc.Versioning), then watch out. For example, the following code will throw an exception after upgrading from 2.1 to 2.2.

[HttpPost("poop")]

public IActionResult PostPoop(PostInput value)

{

return CreatedAtAction(nameof(DummyController.Get), "Dummy",

new

{

id = 3

},

null);

}

Fiddler: HTTP request and response, HTTP 500.

Exception:

An unhandled exception has occurred while executing the request.

System.InvalidOperationException: No route matches the supplied values.

at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)

at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)

at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)

Since this is the new default, we have an option to turn it off and revert back to the 2.1 legacy behavior:

services.AddMvc(o =>

{

o.EnableEndpointRouting = false;

})

.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Fortunately, the fix is already being rolled out.

Update Microsoft.AspNetCore.Mvc.Versioning package to v3.1, and made some changes, like so:

[HttpPost("poop")]

public IActionResult PostPoop(PostInput value, ApiVersion apiVersion)

{

return CreatedAtAction(nameof(DummyController.Get), "Dummy",

new

{

id = 3,

version = apiVersion.ToString()

},

null);

}

Voila.

Fiddler: HTTP request and response, HTTP 201 with correct “Location.”

The bad news is, if you are using OData, then you are left with no choice but to turn it off, at least for now…

To see more samples: https://github.com/Microsoft/aspnet-api-versioning/tree/master/samples/aspnetcore