System Parameters
There are three system parameters that RoutingMiddleware
supports and have a special meaning:
-
{controller}
: This parameter defines a logical name by which a group of controller stored procedures are targeted. It denotes a logical controller that does the job, not a physical object.
-
{action}
: This parameter defines the action that the final controller should carry out in order to fulfill current request.
-
{area}
: This parameter is a logical name that defines an area or group that the controller belongs to. This provides the ability to have controllers with the same name that control different parts of the application.
These system parameters participate actively in determining name of the controller stored-procedure that will be invoked in the next step of request pipeline by MvcMiddleware
(or any middleware that is responsible for invoking controller stored procedure).
If RoutingMiddleware
finds a route match, it adds two more system parameters named $route_id
and $route_sproc
to route values dictionary. $route_id
is the [id]
of matched route and $route_sproc
is the name of controller stored procedure that should satisfy the response.
Determining name of the controller stored-procedure will be explained later in Routing and name of controller SPROC section.
Optional Parameters
Optional parameters are defined using a question mark at the end of their name as in {controller?}
. When a parameter is optional, their equivalent segment in the given URL could be missing.
Example:
/product/{action?}
The above route matches /product
in addition to /product/list
, /product/show
, /product/edit
that the previous route (i.e. /product/{action}
could accept).
Http Method Constraint
Using httpMethods
field we can specify http method constraint i.e. specify a list of http methods that the route will match only when the request is sent with one of them. Value of this field should be a JSON array.
Example:
route |
httpMethods |
/{controller}/{action}
|
[ "GET", "POST" ]
|
Here, the above route will only match with a URL like /product
only when the request is sent using GET
or POST
method. If the request is sent using say PUT
method the route will not match.
Global Mapping
There is a global setting named Chameleon.Routing.HttpMethodAsAction
in chameleon.Settings
table that enacts http method to action mapping. There is also a global setting named Chameleon.Routing.HttpMethodMapping
that defines how http method should be mapped to actions. Here is an example:
route |
/{controller}/{action?}
|
The default value for global Chameleon.Routing.HttpMethodMapping
setting is as follows:
{ "post": "insert", "put":"update", "delete": "delete", "get": "get" }
Now, if current URL misses a value for action
parameter (e.g. current URL is /product
) and the request is sent using say a POST
method, RoutingMiddleware
will uses insert
for the value of action
parameter.
If no value is found in global Chameleon.Routing.HttpMethodMapping
setting for current http method, RoutingMiddleware
will use the http verb itself for the value of action
parameter. For example, if current URL is /product
and it is sent using a PATCH
method, the value for action
parameter will be patch
(in lowercase).
Chameleon.Routing.HttpMethodAsAction
is true (1) by default.
Note: The defaults
field takes precendence over global http method to action mapping. If a default value for action
parameter is specified in defaults
(like { "action": "index" }
), the final value for action
parameter will be index
.
Local Mapping
Sometimes we may want to override global http mapping. We can specify desired http mapping value in the httpMethods
for any http verb we want. Look at the following example:
route |
httpMethods |
/{controller}/{action?}
|
[ "GET", { "POST": "add" }, { "PUT": "edit" } ]
|
Here, the route will only match for requests sent in GET
, POST
and PUT
. Now, if the request misses a value for action
(the URL is e.g. /product
), RoutingMiddleware
will use add
if it is sent in POST
or will use edit
if it is sent in PUT
.
Pay attention that, local http method mapping has more priority over defaults
. Look at the following example:
route |
defaults |
httpMethods |
/{controller}/{action}
|
{ "action": "index" }
|
[ "GET", { "POST": "add" }, { "PUT": "edit" } ]
|
Here, if the request URL is /product
and it is sent using GET
method, the value for action
will be index
since no override value for GET
is defined. However, if the request is sent using POST
, the add
value takes precedence over the default index
value. So, the value of action
parameter will be add
.
As it was stated in System Parameters section, action
plays a primary role in determining name of controller stored-procedure. This is explained in Controller Factory section.
Disable http mapping locally
In some situations, we may want to disable http method mapping for a specific route. As it was said, http method mapping is globally active. Thus, if action
parameter has no value and no default value for action
is specified, RoutingMiddleware
will go for global http method mapping. We can prevent this in a specific route by a setting named httpMethodAsAction
with a false
or 1
value in route's settings
. Look at the following example:
route |
defaults |
settings |
/{controller}/{action?}
|
|
{ "httpMethodAsAction": false }
|
If current URL is /product
, the final value for action
will be an empty string. In fact no value for action
will be set. This enables us to have a single controller stored-procedure for any http method the request is sent with. Note that, in order for this feature to work, we should not specify a default value for action
in the defaults
, otherwise, the default value will be used for action
.