Nancy v0.10.0 – The next step in awesome
TL;DR
A couple of days ago we (finally) managed to get v0.10.0 out of the door and it’s packed of goodies! Diagnostics, razor improvements, bug fixes, weighted request headers, model validation and lots of tweaks to existing features are only a couple of things that went into this release.
The community continue to bless us with their awesome work and this release had 22 authors totaling 250 commits, which is just jaw dropping! That puts us at 65 contributors to the Nancy source code. This release consisted of 23 updated (some new) Nugets and a total of 45 work items! For a complete list of things that’s part of this release (including breaking changes!), head over to check out the milestone at GitHub.
So let’s have a closer look at some of the stuff in v0.10.0!
Validating models just got easy
Craig Wilson contributed some absolutely beautify code to help us get model validation into Nancy. Like all other features in Nancy, the validation stuff is shipped as a set of Nugets with the added ability of hooking in your own validation methods. In this release we ship Nugets to use either DataAnnotations or Fluent Validation to validate your models. Combining this with our model binder and you are definitely on the super-duper-happy-path!
The contribution from Craig also contained the foundation to generate client-side validation based on your model rules, however this release does not contain the code to enable that but it’s definitely something we’ll be looking into in upcoming releases (maybe it will be your contribution that brings this to the community?!)
The Nancy.Demo.Validation project, in the main solution, shows you how to use this feature and uses both DataAnnotations and Fluent Validation. Remember, it’s quite easy to plug in other validation frameworks too!
Making sense of what the client sends you
We gave the RequestHeaders class some love, by adding methods to access all available header names and values through properties. We also made the class implement IEnumerable<> to make it easier to work with the incoming headers.
One of the biggest changes is the presence of weighted headers. The headers that can be weighted not returns IEnumerable<Tuple<string, decimal>>, instead of IEnumerable<string>, and will be sorted in descending order according to their weight. Not only will this enable you to manage weighted headers in a correct way, but it’s also an important piece of the puzzle for the planned content negotiation support, that we will ship in a later release.
Sharpening the Razor
The improvements, made to the Razor view engine, in this release really deserves a blog post of it’s own to make it justice. Despite that, I will give you a mile height overview of the changes and improvements that we’ve made.
One of the things that we (me and Grumpydev) really wanted to sort out for this release was adding in Intellisense for our razor views and I am very happy to say that we’ve managed to do that. It includes a couple of custom build providers that is installed, into the bin folder of your project, with the razor Nuget and adds a couple of post-build events to make sure they stay there. I would lie if I said that getting the build providers to play ball was easy. It’s one of those dark corners of Razor customization that nobody speaks of and it involves quite a bit of Visual Studio magic. So to enable Intellisense, all you have to do is build your project, after installing the Nuget, and the Nancy.ViewEngines.Razor.BuildProviders.dll assembly will be copied into your bin folder. The Nuget will also wire them up for you in the web.config, moar super-duper-happy-path for you!
While doing some refactoring work I also noticed how easy it would be to add support for .vbhtml files, so I did. This should be really handy to help you port that legacy MVC application over to Nancy 😉 The included build providers contains one for these views so you should be able to enjoy Intellisese support if you ever find yourself in the need to use the Visual Basic views with Razor.
Oh, speaking of dark corners of Razor, did you know that ASP.NET MVC installs a global handler for .cshtml and .vbhtml files? We didn’t. At least not until we got a bug report that Nancy wasn’t rendering views with the passed in model. Turns out that if you have a view, with the same name as one of the routes, the request would never be passed to Nancy. Instead the global handler would suck it in and render the view. How nice, right? WRONG! Well after speaking to the Razor team it turns out that you can disable this behavior with the, not so obvious, webPages:Enabled configuration key. We updated out Nuget to stick that into your config file when you install it.
Craig Wilson didn’t only chip in with awesome model validation code, he also added support for @model and @ModelType directives, as well as making the Razor engine smart enough to automatically reference the models assembly or as Craig described it in this pull request
The model’s assembly is now referenced automatically regardless of whether an assembly reference exists in configuration. This makes the "it just works" statement a little more complete. In addition, if specified in configuration, the namespace of the model is automatically included in the razor file.
That’s a very awesome little feature to have around!
We also dropped our dependency on System.Web in the engine which means it will run in client profile. It also means that if you took for granted that it was around in your views then you are going to have to reference the assembly and namespace in the Razor configuration. We thing it’s a small price to pay to get rid of that dependency!
All your Url are belong to us
Two small, but oh so useful, changes where made to the Url type. You can now call ToString() and it will give you a correct string representation of the url. The second thing is that the type will now implicitly cast to an Uri instance, how awesome is that!?
Not more White Screen of Death (WSOD)
Have you ever noticed that if you tried to render a view, that Nancy couldn’t find, you would end up with a blank page? Yeah, not really useful is it? To our defense that we never our intention but we somehow forgot to make it more awesome. That is, until now. As of this release, you will now get a view that tells you that it was unable to locate the requested view and it will also tell you which file extensions, based on the available view engines, that can be used. Also expect a future release to also contain information about the locations that were inspected for the view.
Doctor, what’s wrong with me?!
Do you remember the first time we talked about adding in Diagnostics for Nancy? To be honest I can’t say for sure, but I know it was somewhere around v0.3/0.4 and that wasn’t exactly yesterday. It’s been a long time coming, but I am very pleased to tell you that we’ve included diagnostics in this release! It is important to be aware that this release only contains a couple of diagnostics tools, but we’ve put a lot of work into the diagnostics foundation and it will be really easy for us (that that “us” definitely includes you too! We want your contributions!) to add more diagnostics tool for each new release we make.
The diagnostics contains both request tracing and interactive diagnostics. The interactive diagnostics is where things gets really interesting. It enables you to interactively (duh!) query Nancy, at runtime, to figure out what the heck is going in. Before you get too excited, this is not a query language like SQL where you can just fire of queries, even though it would probably be totally possible to implement (hmmm, any takers?). We are introducing the IDiagnosticsProvider interface and anything that implements this can hand our diagnostic capabilities.
These are, quite literally, normal methods that are exposed on our diagnostics dashboard. It enables you to pass in primitive values and have rich result sets be returned and presented automatically. Anything that implements the interface will automatically be discovered and wired up on the dashboard. Not only that, but you can take full advantage of the, 1st class, dependency injection support of Nancy and take in what ever dependencies you want into your providers, making it super easy to do some pretty advanced stuff. Of course you are not restricted to only take dependencies on Nancy types, there is nothing stopping you from exposing a nice interface over your logs etc.
The providers can, nicely, be dropped into a Nuget and reused across any Nancy project out there!
Wanna know something really neat? The entire diagnostics dashboard is build using Nancy and backbone.js and is embedded into Nancy itself (woah! A Nancy application running inside of Nancy?! Yep!)
It’s extremely fast and easy to use. So how do you get access to the diagnostics goodies? Glad you asked! All you have to do is to run in debug mode (although it’s possible to use it in release mode too, you just need to turn it on) and then browse /_Nancy/ in your application. It will give you some (very) easy instructions (really, it teaches you how to configure a password) to get started.
We’ve only scratched the surface of this!
Moar stuff!
Really, I can’t list em all here so head over to the milestone at GitHub.
So wuzz next?
Well, first of all you won’t have to wait as long for the next release. We are going to try to get this out in about 3 weeks time and plan on focusing on trimming down the pull request queue and fix the reported bugs. We have no major features planned for the next release, but that does not mean that we’re not working on any. Quite the opposite, we are working on getting in support for async routes, content negotiation and proper caching support. We just don’t want to keep other stuff away from you while we work on these things and want to keep doing more frequent releases.
Of course there is always the chance that we manage to finish one of them in time for the next release, or that someone contributes something really awesome that will be included!
Thank you for making v0.10.0 possible!