MVC Routes, Controllers: Actions and Parameters – Part 2

We know little bit  how routing works from Part 1. Lets get into RouteConfig.cs to find a new route. This is only something you need if the default route doesn’t work for you. Let me show you a scenario where new route can help. Lets expect the user comes into the application and search for book by its name. ex.: “books/MVC5” or “books/WCF” or “books/WebAPI”.

In this case the second entry in the url or the second segment in the path is not an action identifier it is a parameter. So it can be MVC5 or WCF or WebAPI or anything.

The default route wont work in this scenario and we don’t want to create an action to our controller for every book name we have, we just want to pass the action as a parameter.  So let us find a new route for this. This is also important that where we should put the new route to the route collection table, because the order is significant.

What the routing engine will do is evaluate each map route that we placed into that route collection and the first one that matched the url will win. The default route we have had is very greedy and it matches nearly any url. So let us add a new one that will satisfy our needs:

route

routes.MapRoute(
name: “Book”,
url: “Book/{name}”,
defaults: new {controller = “Book”, action = “Search”, name = UrlParameter.Optional}
);

Now let us examine our previous url:/Home/Contact

Does our new route satisfy the url needs? the answer is No. Because we have clearly mentioned the controller name is “Book”, so the url will go to next one and invoked the home controller. But if we type url like “/Book/MVC5”, our newly created route will satisfy the url need and invoked the controller. But we didn’t create any controller yet. So we will get 404 error. Let us create a controller named “BookController”.

1

2

If we build the application and try the same url we had before, it will still give us the error. Because according to route configuration it will look for an action / controller public method named “Search”, which is not currently available. Let us create that too and  as we didn’t create any view for this controller let us render text contents for testing purpose.

3

Now build and run the application and type /book, and we have a result, we will see the text on the browser that we have inside controller action.

Always try to avoid the fat controller.Now the question is : what is a fat controller, shortly we can say that:

  • If a controller has domain logic
  • If a controller serves too many requests / too many actions

Never, Ever let your controller suck the life-blood of your domain logic. Controller should be only responsible for:

  • Validating Input
  • Prepare the view
  • Calling Model
  • Return the view / Call another action

Let me point out that, Actions are nothing but public methods inside of a controller class. Anytime you add a public class or controller action, ask a question to yourself “is it url addressable?”. If your answers is No, then the code should not be inside your controller move it somewhere else.

Also don’t write any public method that you don’t expect to access via url. Just keep that in mind and move forward.

Let us try to pull the name value from the url, we can get that by using the following:

var name = RouteData.Values[“name”];

But ASP.NET MVC makes that even more easier to access because you add a parameter to an action. What the MVC framework will do is that try to find something that matches with the parameter name and will just give it to you. It will do everything to populate that parameter, it will look all around the request . It will look into the routing data, so things will be picked from the url. It will looked into the query string  and also at posted form values.

Let us add a parameter to that Action method:

public ActionResult Search(string name)

In the case to /Book/WCF , the MVC framework will see , I need a parameter called “name” , so extract something called name for  routedata/ querystring / etc..

Let us get that name by using

var bookName = Server.HtmlEncode(name); // to avoid some sort of malicious script, tag or something like that

That was all for today. As we move further, we will see more advanced features… Keep Smiling 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s