To use them in view, next step in Asp.Net would be to drag&drop them into view, css in <head> and scripts to bottom of <body>. VS produces proper tags for them:
If you run application now, you can see that all already works, everything loads just fine:
That is very nice, as by default OWIN doesn’t serve static resources (you must configure simple FileServer, which you can do anyway if you want to enable file browsing in some of your folders, but then add builder.UseNancy() line at end of Configure method, as Nancy handler is greedy and it will handle request before it gets to file server). But even without it, this works because of default conventions in Nancy, which are summed in first sentence on that page: stick stuff in /Content .. done.
As a side note, notice that everything is loaded within 200ms,
which is nice, especially when having in mind that average
human needs 300-400ms to perform an blink of eye 🙂
So, this makes again another very simple blog post, to summarize plot started by the title, there is nothingneeded to do to serve static resources,if you use Nancy on OWIN. Nancy already takes care of it, same way as it does on ASP.NET, so no need to worry what is underneath.
To start building some app, I need to add some client-side functionality. If I replace home.html with basic bootstrap template, and add ng-app directive to html tag, I can check if angular works:
And, as it shows ‘it works!’ in place where I have put curly brackets, I’m happy. As this is only static html, Visual Studio Page Inspector will render exactly same result as browser. Now, I’ll add application root to <base> tag, which is by default “/”, but if you ever hosted your application in IIS, and if it was not in root, but in some path (like localhost/myapp) then you know how important was to render all resources with @Url.Content helper, because all you resources would be broken otherwise. So, after I added <base href=’/’ /> and changed css and script links from relative to app-relative (removed ‘../’ prefix), I’m adding project root folder to local iis, into http://localhost/playwithowin app:
Loading project url in browser shows that OWIN works on IIS, that’s nice, but that also kills css and js resources loading, because they are loaded from root of app, which is now wrong, and it is common thing happening after you put app in virtual folder when you don’t use @Url.Content helpers. Now my angular doesn’t work properly anymore, because it tries to load it from http://localhost/Scripts/angular.js instead of http://localhost/playwithowin/Scripts/angular.js:
To fix this, I will fix path in <base> tag: <base href=”playwithowin” />
That makes everything fine again:
Next problem is, you may deploy your app to different environments, which may be on same server, in different virtual folders, or you may even want to have multiple instances of application on same server. To automate this, I’ll send base path from server:
Nancy view can accept anonymous view model, and I assign base path of request url (that is “Nancy root”) to server-side view model.
To use it in view, just use Razor-like syntax in html file! Thanks to The Super Simple View Engine, which is by default used in Nancy, it will be replaced with server variable:
So, to summarize this post, so far, using Nancy on OWIN is not different than using it on Asp.Net, and for many cases, Nancy’s Super Simple view engine is more than enough for what you need. If you still need Razor, just install NuGet: RazorEngine.
Next step in creation of app would be adding some custom js and html files. I will add angular app, one view (welcome.html), controller (WelcomeCtrl), and use them in home.html (set app name in ng-app in html tag, add div which references new view, and add references to new js files):
This is now very simple functionality, but we already have 3 referenced js files. Angular automatically loads views, but js files must be loaded explicitly, and in average application, with well separated responsibilities, there could be hundreds of js files. That could be managed using some AMD framework, but that is one of aspects where Asp.Net rules with bundling & minification, and I like it. It reduces number of requests, and we can leverage caching because it allows to automatically expire cache by varying url. In next post I will be looking on ways how to achieve same thing here.