Starting from Vici MVC v2.0, a very flexible URL routing engine is available which allows you to map any URL to any controller, optionally passing parameters that are embedded in the URL.
URL routing can be specified in two ways:
To add routes to the URL routing table, you should call the AddRoute() method on the WebAppConfig.Router object. This should be done in the application's Init() method.
For example:
public class App { public void Init() { WebAppConfig.Router.AddRoute("products/overview","Products","Overview"); WebAppConfig.Router.AddRoute("product/{id}","Products","Details"); WebAppConfig.Router.AddRoute("report/{reportName}","Report", "Show", new RouteParameter("name", "{reportName}"); WebAppConfig.Router.AddDefaultRoutes(""); } }
You can insert tags ({tagname}) in the URL portion and you can then reuse these tags in the controller, action or parameters.
In the example above, the URL mapping will be:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/products/overview | Products | Overview | ||
| ~/product/detail/{id} | Products | Details | id = {id} | |
| ~/report/{reportName} | Report | Show | name = {reportName} | |
| ~/{controller}/{action}/{id} | {controller} | {action} | id = {id} | |
| ~/{controller}/{action} | {controller} | {action} | ||
| ~/{controller} | {controller} | Run | ||
(the last 3 routes are default routes, explained below)
This is an example of some URLs and their mapped controllers and actions:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/product/45 | Products | Details | id = 45 | |
| ~/products/overview | Products | Overview | ||
| ~/about | about | Run | ||
| ~/contact | contact | Run | ||
| ~/report/TotalSales | Report | Show | name = TotalSales | |
Calling the method WebAppConfig.Router.AddDefaultRoutes() adds some default routes to the routing table. This method needs to know the page extension to use for the default routing rules. For example, if you call AddDefaultRoutes("aspx"), the default routes will be:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/{controller}/{action}/{id}.aspx | {controller} | {action} | id = {id} | |
| ~/{controller}/{action}.aspx | {controller} | {action} | ||
| ~/{controller}.aspx | {controller} | Run | ||
Passing an empty extension or null results in the following default routes:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/{controller}/{action}/{id} | {controller} | {action} | id = {id} | |
| ~/{controller}/{action} | {controller} | {action} | ||
| ~/{controller} | {controller} | Run | ||
It's possible to validate URLs using regular expressions. For example, let's take the following URL routing entry:
WebAppConfig.Router.AddRoute("product/{id}","Products","Details");
What if {id} should always be a number? The answer is to add a RouteValidator to the route:
Route route = new Route("product/{id}", "Products", "Details"); route.AddValidator(new RegexRouteValidator("id", @"\d+")); WebAppConfig.Router.AddRoute(route);
By default, when validation fails for a route, the URL router will continue checking the other routes. In the example above, this is probably not what we want. You can specify two additional parameters (enumeration) of type RouteValidationAction. The first parameter is the action to perform when validation passes, and the second parameter is the action for failed validation.
The RouteValidationAction enumeration can have the following values:
| None | No action is performed and the next validation on the route will be executed | |
| Skip | The current route will be skipped and routing engine will check the next route in the routing table | |
| Error | The route fails and no further routes and validations will be checked | |
| Accept | The route will be accepted. No further validations will be checked | |
None is the default action for a passed validation, and Skip is the default action for a failed validation.
To get the desired behavior, we will change our example:
Route route = new Route("product/{id}","Products","Details"); route.AddValidator( new RegexRouteValidator("id", @"\d+", RouteValidationAction.Accept, RouteValidationAction.Error) ); WebAppConfig.Router.AddRoute(route);
In addition to specifying the URL routing table using the WebAppConfig.Router object, you can also use the [Url] attribute on controller classes and controller actions:
[Url("products/{action}", "{action}")] public class Products : Controller { public void Overview() { } public void Detail() { } }
In the example above, the following entries will be added to the URL routing table:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/products/{action} | Products | {action} | ||
So, "~/products/overview" will be routed to the Overview() method of the Products controller
It's also possible to define more than one [Url] attribute:
[Url("products/overview","Overview")] [Url("products/detail/{id}", "Detail")] public class Products : Controller { public void Overview() { } public void Detail(int id) { } }
In the example above, the following entries will be added to the URL routing table:
| URL | Controller | Action | Parameters | |
|---|---|---|---|---|
| ~/products/overview | Products | Overview | ||
| ~/products/detail/{id} | Products | Detail | id = {id} | |
There are a few limitations when using the [Url] attribute for specifying routing: