Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NancyFX Catch All route

Does NancyFX supports ASP.NET MVC like 'Catch All' route? I need one, that basically match every URL. This is very handy for building up Single Page applications.

Is that possible?

like image 574
Alexander Beletsky Avatar asked Oct 01 '12 19:10

Alexander Beletsky


4 Answers

Tested in Nancy version 0.23.2

Get[@"/(.*)"] did not work for me as a catch-all route. The routes "/", "/foo/bar", and longer routes would not catch. It seems like there's no getting around having to define a Get["/"] route for the root URL. Nothing else seems to catch it (tried Get["{uri*}"]). Here's how I ended up defining my routes (keep in mind I'm doing this for an Angular application):

Get["/views/{uri*}"] = _ => { return "A partial view..."; };
Get["/"] =
Get["/{uri*}"] = _ =>
{
    var uri = (string)_.uri;// The captured route
    // If you're using OWIN, you can also get a reference to the captured route with:
    var environment = this.Context.GetOwinEnvironment();// GetOwinEnvironment is in the 'Nancy.Owin' namespace
    var requestPath = (string)environment["owin.RequestPath"];
    return View["views/defaultLayout.html"];
};

It's important to understand Pattern Scoring. The route patterns are weighted, if two routes match the same url segment, the higher score wins. The catch-all pattern is weighted 0 and even though the /views/{uri*} route pattern is also a catch-all, it starts with a literal, which is weighted 10000, so it will win out on all routes that start with /views.

Here's more info on Accessing Owin's Environment Variables. Note that the captured uri variable and requestPath will be slightly different. The requestPath will start with a / where as the uri variable will not. Also, if the matched route pattern is Get["/"], uri will be null and requestPath will be "/".

The Views route will return a partial html file, based on the url path, and all other routes will return the default Layout page that will bootstrap the SPA.

like image 56
nwayve Avatar answered Oct 03 '22 01:10

nwayve


Yes, using Regex

Get[@"/(.*)"] = parameters => {
    return View["viewname", parameters];
};

But you don't really need it for building a Single Page Application with NancyFX - you can just use Get and Post with all your routing logic and still have a single page app.

like image 43
synhershko Avatar answered Oct 03 '22 03:10

synhershko


An updated answer for whom @synhershko 's solution does not work. Try:

Get[@"^(.*)$"] = parameters => {
    return "hi";
};

This will capture all paths except for the index page. I am not sure if this will work in the context of Angular, but this worked for me when trying to hack together a simple server with just one handler.

like image 23
ymbcKxSw Avatar answered Oct 03 '22 01:10

ymbcKxSw


Answer provided by @synhershko does not work for me. It does not handle /users/2 or any other route containing more segements.

Below code works on my machine ;) :

public class IndexModule : NancyModule
{
    dynamic IndexPage() { return View["Index"]; }

    public IndexModule()
    {
        Get["/"] = _ => { return IndexPage(); };
        Get["/(.*)"] = _ => { return IndexPage(); };
        Get["/(.*)/(.*)"] = _ => { return IndexPage(); };
        Get["/(.*)/(.*)/(.*)"] = _ => { return IndexPage(); };
    }
}

My solution is not perfect, cause it does not match everything. I repeated as many '/(.*)' as in my longest Angular route.

like image 22
Krzysztof Morcinek Avatar answered Oct 03 '22 03:10

Krzysztof Morcinek