My Development Blog

My Development experiences

Archive for June, 2013

MVC Part1 – Routing

Posted by ipwright83 on June 14, 2013

I’ve been spending some time watching videos to learn ASP.NET and decided to blog the useful nuggets of information that I’ve learnt to try and help myself remember them, and share them with anyone interested.

Routing

So what’s routing? Routing is what MVC uses to determine where an HTTP request should go. When you make a request such as http:\\localhost\home\about this gets split up into sections and determines which controller and method should be visited.

Routing is setup in the global.ascx file with the following line:

RouteConfig.RegisterRoutes(RouteTable.Routes);

So lets take a look at the RouteTable class:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

The first line to note is the routes.IgnoreRoute. This prevents .axd files from being included in the routing system as these are handled by MVC specifically. Following that a single route is setup which matches a particular pattern of {controller}/{action}/{id}, and a default is set. This means when we visit /Home/About we can see that it will use the Home controller, and the About action (aka Method).

We could create our own route, for example to define a system for controlling the language, so whenever /language/ is used it will direct to our controller. It should be noted that the default matches {controller} first which is essentially a variable parameter, making it very greedy. Therefore we need to place our custom route before it:

routes.MapRoute("Language", "language/{name}",
				new { controller = "Language", action = "Search", name=""});

At this point we’ll get a 404 or ‘Page not Found’ error if we try to navigate to /language/english. The reason for this is because we don’t yet have an appropriate controller. If we create a new LanguageController and rename the ‘Index’ method to ‘Search’ then we should be able to test the system.

public class LanguageController : Controller
{
    //
    // GET: /Language/
    public ActionResult Search(string name)
    {
    	string message = Server.HtmlEncode(name);
        return Content(message);
    }
}

Notice here that the name property has been passed in as a parameter. This is because the Controller will automatically search through the routing data, querystrings etc. and fill it in for us. Also remember to protect your strings against potential attacks, the Razor engine introduced later will do this for us, but for custom Actions we need to do this ourselves manually using helper methods such as Server.HtmlEncode().

What is interesting is that this information can be interrogated later on within your controller, for example:

public ActionResult Index()
{
	var controller = RouteData.Values["controller"];
	var action = RouteData.Values["action"];
	var id = RouteData.Values["id"];

	string message = controller + "::" + action + " " + id; 
	ViewBag.Message = message;
}

You can then test this by running your application and going to /Home/Index/49833345.

There are some other useful things to note, when dealing with URL’s you should generally use tilde ~ which means from the ‘root’, this means you don’t have to try and figure out complex web locations and they can instead all be relative. An example: Server.MapPath(“~/Content/site.css”) which would turn this into a real URL.

When you add a method to a controller, by default it’s name will be used as the Action, however using the ActionAttribute it is possible to change this behavior to use a different name, in this example to use the action named Modify:

[ActionName("Modify")] 
public ActionResult Index()
{}

You can also specify verbs which ensures the action is only called for a specific HTTP requests (e.g. Get, Post, Put). This method also allows two action methods to have the same name. You can do this using attributes again:

[HTTPPost]
public ActionResult Index()
{}

Finally it is also possible to apply action filters to commands, for example to ensure only people with certain permissions have access to an action.

[Authorisze(Roles="Admin")]
public ActionResult Search() {}	
public ActionResult Edit(string departmentName) {}
Advertisements

Posted in Uncategorized | Leave a Comment »