An IRouter that can handle a request now sets the resulting RequestDelegate on RouteContextinstead of setting the IsHandled flag as mentioned below. The invocation of the request delegate is now centralized on the RouterMiddleware.

On previous versions of ASP.NET, routing started as a feature of MVC and was later extracted to a dedicated assembly (System.Web.Routing) and integrated on .NET. When Web API was released it brought the need of hosting outside of IIS, which required a dedicated routing system (actually a facade that could delegate on ASP.NET routing when hosting on IIS).

Similar to how MVC and Web API are unified, there’s now a single unified routing system, which includes features previously found on both routing systems and an improved syntax for both convention- and attribute-based routes; constraints, optional parameters and default values can all be specified inline on the route template. In addition, a route handler can now return control to the routing system indicating that it didn’t handle the request, allowing the following routes/handlers to be attempted. This didn’t happen on previous versions: if, for instance, an MVC route template was matched but couldn’t actually be resolved (e.g. no controller with the attempted name) an HTTP not found was immediately returned.

As you might expect by now, ASP.NET 5 routing is implemented as a middleware that can be included on the request pipeline: the RouterMiddleware. To include it on the pipeline one can use the UseRouter extension method depicted below:

However, the RouteContext includes a bit more information, namely the RouteData and the IsHandled flag. The RouteData contains things such as the values extracted from the route template and the available routers; the IsHandled flag is used by the routers to signal if they were able to handle a request.

ASP.NET includes some implementations of IRouter that are the base for application routes. One of them is TemplateRoute, which pairs a route template with another IRouter (the target); if the route template matches the current request, the route values are extracted from the template parameters and the request is forwarded to the target router.

If the name route value is present, the handler writes the response and marks the route context as handled; otherwise, it returns control to the parent router for further processing. We can then define a route template and include our handler on the pipeline by combining it with a TemplateRoute on the Startup class:

Note the usage of an inline constraint on the route parameter. If we run the app we can see the expected output on the browser.

If we use an URL that doesn’t match the route (e.g. use only numbers on the name segment) we’ll get an HTTP not found or the result of another middleware on the pipeline that handles the request.

Another built in router is RouteCollection, which takes an ordered list of routers and returns when one of them handles the request. The following code excerpt illustrates the usage of a route collection; I also added a default value for the name parameter as an example of default values.

Some (bad) things in ASP.NET come back from time to time and custom error pages are one of them. A lot has been written on this topic – specifically when using MVC – but I found myself again struggling to get it right. However, I finally got a solution that is a good trade-off. My requirements are similar to everyone’s:

Preserve request URL.

Return proper status code (namely 404 and 500) and content-type.

Cover IIS errors, since it’s likely that unmanaged stuff is is place (e.g. static file handler).

You might need to unlock some attributes on the httpErrors section at machine level. Also, I set errorMode to Custom to always get the custom error pages when testing. In production you’d likely set it to DetailedLocalOnly.

How does it work and what is the trade-off?

The trade-off is between the amount of code/configuration and the flexibility of the resulting error pages. In my solution there’s nothing else to configure or code, but you must use static error pages. This may not give you all the flexibility and duplicates a bit of HTML (some of the site’s layout, assuming that the error pages will look the same), but covers all the error cases. How? The trick is on two of the attributes:

defaultResponseMode=”File” – Ensures that the response content-type is correct and also preserves the status code.

existingResponse=”Replace” – Ensures that any existing response is always replaced by the one configured on httpErrors. This is important because sometimes ASP.NET already produces a response (e.g. not found pages). This option is not usually mentioned on community answers.

So, it doesn’t matter what happened on the server, this configuration will always kick in.

Other solutions

This post is a commonly referenced resource (even by MSFT). It uses a static-ish page approach which configures both ASP.NET custom errors and IIS errors. This works fine, but has more configuration and more code and duplicated HTML.

There’s also a NuGet package to handle 404 on MVC. It wires-up on different MVC extensibility points to catch all the not found situations. You could complement this with the built in HandleErrorAttribute, but it leaves out errors than happen on ASP.NET prior to MVC and IIS errors (e.g. file not found).

If you need to generate the error pages dynamically (using a controller/view), this question on Stackoverflow discusses different alternatives. Note that when you do this, you might get errors when trying to generate the custom error page. Inception! Also, depending on which error configuration section you use, some errors may be left out.

Conclusion

IIS error pages seem to be the less cumbersome solution for custom error pages. If you’re willing to have static HTML pages, it’s probably as good as it gets. I wasn’t able to find any other solution that covers as many cases and is worth the effort.

Microsoft recently released beta 5 of ASP.NET 5 and it includes a lot of bug fixes, API reviews and some package refactoring, namely on MVC. It’s nice to see this effort on tidy and coherent APIs. Here are some things I find worth mentioning:

As previously mentioned there’s a visible effort on API/packages organization which is visible if we browse on the change logs for the individual components. Nevertheless, I get the feeling that “it is almost there” for most of the components.

In addition to the beta 5 release, there are some other news worth mentioning:

There’s a new Announcements repository where the major changes on ASP.NET 5 are announced. Worth subscribing!

Visual Studio 2015 and ASP.NET 4.6 will ship on the July 20! ASP.NET 5 stuff will be beta and updated later.