ASP.NET MVC Tip # 30 – Create Custom Route constraints

Tram Ho

When you create an MVC route, you can add constraints to a route. For example, the following route will direct browser requests to the controller named Blog and the action named Archive:

This route is named BlogArchive, mapping three parameters. The controller parameter is set to Blog and the action parameter is set to Archive. Finally, the entryDate parameter takes its value from the entryDate parameter in the URL.

Unfortunately, this route fits too many requests. It fits:

You don’t want entryDate to accept values ​​like 12 or apple. These values ​​cannot be converted to dates. You can fix this problem with the BlogArchive route by adding a constraint to the entryDate parameter like this:

This new version of the BlogArchive route includes a constraint for the entryDate parameter. The constraint requires the entryDate parameter to match the date pattern as 12-25-1966. A URL like / Archive / apple will not satisfy this constraint and the route will not match.

Two types of route constraints

The URL Routing framework recognizes two different types of constraints. When you provide a constraint, you can provide a string or you can provide a class that implements the IRouteConstraint interface.

If you provide a string for a constraint, that string is interpreted as a regular expression. For example, the entryDate constraint we discussed in the previous section is an example of a regular expression constraint.

Another option is to create a custom constraint by creating an instance of a class that implements the IRouteConstraint interface. The URL Routing framework includes a custom constraint: the httpMethod binding.

Use HttpMethod Constraint

You can take advantage of HttpMethod Constraint to prevent controller actions from being called unless the action is called using a specific HTTP method. For example, you might want an controller action called Insert () to be called only when performing a POST HTTP operation, not when performing an HTTP GET operation.

Here is how you can use the httpMethod constraint:

The final parameter passed to the MapRoute () method represents a new httpMethod constraint called httpMethod. If you post an HTML form to / Product / Insert URL, the controller action Product.Insert () will be called. However, if you only request / Product / Insert using HTTP GET, then this route will not match.

By the way, the name of the constraint does not matter. Only value is important. For example, the following code works the same as the previous code:

In this code, HttpMethodConstraint is named Grendal. You can name the constraint whatever you want and the constraint will still work.

Create an Authenticated Constraint

You create custom constraints by implementing the IRouteConstraint interface. This interface has a method you must implement: the Match () method.

For example, the code in Listing 1 represents a custom constraint that prevents unauthenticated access to a URL:

Listing 1 – AuthenticatedConstraint.cs

Notice that Listing 1 contains a class that implements the IRouteConstraint interface. The Match () method checks to see if the current user is authenticated and returns True or False.

Here’s how you can use AuthenticatedConstraint when creating routes:

This constraint prevents requests from anonymous users from accessing the Admin route.

It is important to understand that although this anonymous user cannot access a specific route, the latter route can map an anonymous user to the same controller and controller action. For example, if the Admin route follows the Default route, the user can access the Admin pages:

For this reason, you should explicitly exclude Admin pages from the Default route with an explicit constraint.

Create NotEqual Constraint

The easiest way to exclude a set of pages that match a specific route, is to take advantage of custom route constraints.

Listing 2 – NotEqualConstraint.cs

This route will not match any request when the controller parameter receives the Admin value. For example, this route will not match URLs / Admin / DeleteAll or / Admin / Index.

Create Local Constraint

You can also create a custom constraint to prevent requests from matching URLs unless the request is made from the local machine. This type of constraint can be useful for restricting access to webmasters.

Listing 3 contains the code for the LocalConstraint class. Listing 3 – LocalConstaint.cs

LocalConstraint just needs to check if the current request is a local request by taking advantage of the Request.IsLocal property. This property returns True when the server is equal to localhost or 127.0.0.1.

Check Route Constraints

So how do you check for route constraints? It’s easy, it’s fake HTTPContext. The test in Listing 4 can be used to verify that the Product route includes an HTTPMethod constraint.

Listing 4 – A unit test for the httpMethod constraint Listing 4 – A Unit Test for the HttpMethod Constraint

The unit test in Listing 4 consists of two tests. First, the URL / Product / Insert is requested by performing a POST operation. The product route must be matched in the route table. Next, the same URL is requested while performing the GET operation. The product route will not match when executing GET.

The Unit Test in Listing 5 shows how you can test AuthenticatedConstraint. Listing 5 – Unit Test for AuthenticatedConstraint

This unit test also includes two tests. First, a fake user was created with the help of the FakeIdentity class. When the URL / Admin / Index is requested with the fake identity in the context, the Admin route will match. When the same URL is requested anonymously, no routes match.

In brief

In this tip, you learned how to create custom route constraints. We have created three custom route constraints: AuthenticatedConstraint, NotEqualConstraint and LocalConstraint. I also showed you how you can build unit tests for routes that include custom constraints.

Source: https://weblogs.asp.net/stephenwalther/asp-net-mvc-tip-30-create-custom-route-constraints

Share the news now

Source : Viblo