I was recently working on a project, where I had a need to inherit routes from a generic base Web API controller. This is not supported by Web API out of the box, but can be enabled with a tiny configuration tweak. Let’s have a look.
Over the past 4 years or so, I have worked on many Web API projects, for a lot of different clients, and I thought I have seen almost everything.
Last week I came across an interesting new (well, at least to me) scenario though – with the requirement to run two Web API pipelines side by side, in the same process. Imagine having /api as one Web API “instance”, and then having /dashboard as completely separate one, with it’s own completely custom configuration (such as formatter settings, authentication or exception handling). And all of that running in the same process.
More after the jump.
One of the functionalities I had to use fairly often on different ASP.NET Web API projects that I was involved in in the past was IP filtering – restricting access to the whole API, or to parts of it, based on the caller’s IP address.
I thought it might be useful to share this here. More after the jump.
As you may have learnt from some of the older posts, I am a big fan, and a big proponent of attribute routing in ASP.NET Web API.
One of the things that is missing out of the box in Web API’s implementation of attribute routing, is the ability to define global prefixes (i.e. a global “api” that would be prepended to every route) – that would allow you to avoid repeating the same part of the URL over and over again on different resources. However, using the available extensibility points, you can provide that functionality yourself.
Let’s have a look.
Sometimes you have resources in your code that are implementing IDisposable, and that you’d like them to be disposed only at the end of the HTTP request. I have seen a solution to this problem rolled out by hand in a few code bases in the past – but in fact this feature is already built into Web API, which I don’t think a lot of people are aware of.
Let’s have a quick look.
Migrating an MVC 5 project to ASP.NET 5 and MVC 6 is a big challenge given that both of the latter are complete rewrites of their predecessors. As a result, even if on the surface things seem similar (we have controllers, filters, actions etc), as you go deeper under the hood you realize that most, if not all, of your pipeline customizations will be incompatible with the new framework.
This pain is even more amplified if you try to migrate Web API 2 project to MVC 6 – because Web API had a bunch of its own unique concepts and specialized classes, all of which only complicate the migration attempts.
ASP.NET team provides an extra convention set on top of MVC 6, called “Web API Compatibility Shim”, which can be enabled make the process of migration from Web API 2 a bit easier. Let’s explore what’s in there.
In ASP.NET Web API, if the incoming does not match any route, the framework is simply hard wired to return 404 to the client (or possibly pass through to the next configured middleware, in case of an OWIN hosted Web API). This is done immediately, without entering anywhere further down the pipeline (i.e. message handlers would not be invoked).
However, an interesting question was posted recently at StackOverflow – what if you want to override that hard 404, and given your specific routing requirements, respond to the client with a different status code if a specific route condition fails?
I already answered at StackOverflow, but decided this deserves a blog post regardless.
As you might now by now, last month my ASP.NET Web API 2 Recipes book was released by Apress. The book contains over 100 recipes covering various Web API scenarios that aim to help you save some headaches when working on your current or next Web API project.
Each of the recipes has got an accompanying Visual Studio solution, which illustrates the given problem and presents a solution in a simple, isolated manner.
Obviously, it would be great if you went ahead and bought a book (then you would get an in-depth analysis of each case), but the source code itself is available for free at Github and as a download from Apress.
I hope it becomes a useful collection, illustrating how to deal with various Web API problems/scenarios.
Please note that some of the early examples might appear simple or even trivial – that’s the case with introductory recipes, where the gist of the matter is discussed in the book itself.
I have seen in some StackOverflow questions that the examples on Github have already helped a couple of folks, which is fantastic. You can find a summary of the samples below – they are structured in the book and in the repository the same way.
When you are developing an ASP.NET Web API application, you can chose whether you want to return a POCO from your action, which can be any type that will then be serialized, an instance of HttpResponseMessage, or, since Web API 2, an instance of IHttpActionResult.
Let’s have a look at what really happens under the hood afterwards, and discuss some of the things about the response pipeline that you might have not known before.
ASP.NET Web API provides an IUrlHelper interface and the corresponding UrlHelper class as a general, built-in mechanism you can use to generate links to your Web API routes. In fact, it’s similar in ASP.NET MVC, so this pattern has been familiar to most devs for a while.
The main problem of it is that it’s based on magic strings, as, to generate a link, the route name has to be passed as a string literal. Moreover, all the parameters that are required to built up the link, are simply a set of name-values, represented by a dictionary or an anonymous object, which is hardly optimal. Code is not coherent, refactoring becomes a pain and in general error potential is high.
My friend, and one of the most respected folks in the Web API community, Pedro Felix, has created a library called Drum, designed to avoid the pitfalls of the UrlHelper, allowing you to build links for Web API direct routing (introudced in Web API 2) in a strongly typed way.
Drum works with any direct routing provider, including my own Strathweb.TypedRouting.