So far we have focused on dynamic content. Our handlers in the TodosModule
project have returned either data or views that depended on the data in our data store and the data in the request.
In this recipe, we look at how to serve static content. This can be images, icons, CSS files, JavaScript files, and plain old HTML files.
This recipe builds on the code from the previous recipe, so have your copy of that ready. If you have not coded along, you can start off from the code for the Adding views (Intermediate) recipe in the code download.
The following steps show how to add static content in your application:
First note that the code in the code download already has static content since the Routes and model binding (Intermediate) recipe, where the
backbone.js
based todo SPA was added as a client to ourTodoNancy
server-side application. Thebackbone.js
todo SPA consists of theindex.htm
file in theViews
folder and a bunch of JavaScript of CSS files in theContent
folder. Theindex.htm
view is returned from theHomeModule
class and is therefore handled as dynamic content. The files in theContent
folder on the other hand are not returned by any handlers in any Nancy modules. They are just served directly by Nancy. We have done nothing special to make this work. We just rely on Nancy—by convention—to consider everything in theContent
folder to be static content and make it available through HTTPGET
requests to/Content/{path-to-file}
.Since
TodoNancy
is first and foremost an API, we want to provide documentation for it. To this end, we want to serve some static HTML files from/docs
. Add a new file,DocumentationTests
, to theTodoNancyTests
project, and add the following test to it:[Fact] public void Should_give_access_to_overview_documentation() { var sut = new Browser(new Bootstrapper()); var actual = sut.Get("/docs/overview.htm", with => with.Accept("text/html")); Assert.Equal(HttpStatusCode.OK, actual.StatusCode); }
This simply checks that our application accepts requests for
text/html
to/docs/overview.htm
and responds with a200 OK
status code. Right now the test fails. To make it pass, we need to do a few things. First, we add aDocs
folder and aDocs/overview.htm
file to theTodoNancy
project. You can put whatever HTML you want in the new file as it doesn't matter; for instance, the following code will do:<html> <head> <title>Todo Nancy API Overview</title> </head> <body> ... documentation would go here ... </body> </html>
Make sure the
Copy to Output Directory
property foroverview.htm
is set toCopy Always
.Second, we add a custom convention that tells Nancy to treat anything inside
Docs
as static content. Add the following code tobootstrapper
:protected override void ConfigureConventions(NancyConventions conventions) { base.ConfigureConventions(conventions); conventions.StaticContentsConventions.Add( StaticContentConventionBuilder.AddDirectory("/docs", "Docs") ); }
This accesses the list of conventions for where to find static content and adds an extra convention. In other words, the default Nancy convention is preserved alongside our custom convention. Our convention is built using the
StaticContentConventionBuilder
helper API. This allows to easily build conventions for static content folders and for individual static content files. More involved schemes can also be created by coding up a convention by hand.Re-run the test and watch it pass. If you want you can also point your browser to
/Docs/overview.htm
.
Nancy makes a lot of things easy by providing reasonable conventions out of the box. One of these conventions is that files in /Content
are considered as static content. We saw how to augment this convention with our own convention in the override of ConfigureConventions
in the bootstrapper
code. This bootstrap
method similarly allows for setting up custom conventions; for example, you can view locations and culture in case the default conventions do not suit you.