URL Routing in ASP.NET MVC – Part 2

This post continues our discussion on how ASP.NET MVC’s URL Routing System works. I assume you have already read Part 1 of the series cause I ‘m gonna work on the project we have created. In our MVC solution project we had two controllers named “ProductController” and “SimpleController” plus a View named “DisplayActionController” in the Views/Shared folder.

Delete the code we have added in the previous post inside the “RegisterRoutes” function in the RouteConfig.cs file, where we declared our own routes. We are going to see new features now. The first feature we will examine is how to create custom segments. Till now we have seen the MVC build in segments “controller” & “action”, which apparently correspond to the respective controller and action that will be used to service the requested URL. To start with, we ‘ll create a route with a custom segment variable, named Id. Paste the following code to the RegisterRoutes function.

Notice the {id} segment we added and it’s default value “CustomSegmentId” as well. You can access any of the segment variables in the action methods, through the RouteData.Values property. To demonstrate this, first add a new action method in the SimpleController:

Build and run your application. Navigate to the following URL (always use your own port number).

http://localhost:49529/Simple/MySegmentVariable

Notice the “CustomSegmentId” default value passed for the Id custom segment. Request another URL, passing this time a value for the Id segment. You should get the imputed value (“Test” in the following case).

http://localhost:49529/Simple/MySegmentVariable/Test

You can access your custom segment variable with a more legitimate way than using the RouteData.Values property. Simply change your action method to accept a parameter with name same as the segment variable.

The application will run in the same way as before. The MVC Framework, will search in the invoked action a parameter with name as the custom variable, hence “Id”. If it finds a match, it passes the value from the URL to the method. Be aware that if we had defined the Id parameter as int in our action method, the framework would try to cast the URL value to int. You can test it, by changing your id parameter to int and requesting a URL, where you pass a string “test” for the id segment. You will get an error cause “text” couldn’t be casted to int.

You can make your custom segment variable optional, by removing it’s default value and replacing with a “UrlParameter.Optional” definition. Change the route we have defined like this.

If you request the “MySegmentVariable” action now, without providing a value for the id custom segment, a null value will be passed.
We saw before how to declare a default value for a custom segment variable. Some developers prefer not to declare a default value in the “RegisterRoutes” function as we did, but instead inside the action’s parameter declaration.

but instead of having one SimpleController class, have two with different namespaces? Test this, by creating a new SimpleController controller inside a new folder named “OtherControllers”. Change the new SimpleController’s content to the following, build and run your application.

To address this problem, you need to tell MVC Framework your preferred namespaces to look when it searches for controller classes. You declare your preferred namespaces with an array of strings like this.

Here we told MVC to search first in the UrlRouting.OtherControllers namespace, which means that if a “Simple” controller class was requested from the URL, then the UrlRouting.OtherControllers.SimpleController will be chosen.
Mind that, if you declare both the namespaces in the string array for preferred namespaces, you will get the same conflict error. This means that if you want to use both the namespaces you need to provide two different routes, defining in each of them your preferred namespace.

Another important feature you want to learn is how to constrain a route, using regular expressions. For example, consider that you want a specific route, to make use only controllers start with the letter “S”. You define such a route like this.

We declared a constraint using an anonymous type again, between the default values and the preferred namespaces. I added a new JunkController inside the OtherControllers folder to test if the constraint works.

Here we told the MVC that this route accepts only controllers with name starting with “S” and only two actions can be invoked to that kind of controllers: Either an Index or a NewIndex action. Before testing this feature I added two actions in the OtherControllers.SimpleController.

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!