Sep 25, 2015

Controllers In Mvc

Controllers are basically nerve of ASP.Net MVC as it is going to be the 1st recipient which is going to interact with incoming HTTP Request. So, controllers are going to decide which model is going to be selected, then taking the data from the model and passing the same to the respective
view, hence finally view is going to be rendered. So, controllers in a nutshell are basically controlling the overall flow of the application taking the input and rendering the proper output. Since, we have selected internet template while building the application, so we have been presented with two default controllers called as


Home Controller: - It will render the home page of the application.
Account Controller: - It will render the Login/Registration page of the application



Below, is the sample snapshot of the Home controller being created by the Visual Studio.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;


namespace MovieReview.Controllers
{


public class HomeController : Controller
{


public ActionResult Index()
{


ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC
application.";
return View();
}


public ActionResult About()
{


ViewBag.Message = "Your app description page.";
return View();

}

public ActionResult Contact()
{


ViewBag.Message = "Your contact page.";
return View();


}


}


}

Now, when you run the application by clicking F5 button, it will simply render the Home view with the above welcome message printed on screen as shown below in the snapshot.
However, you can verify the same by putting one debug point in the home controller and see how the control is flowing and how view is getting rendered over here.



Now, when you run the application, you will see that control has hit the break point and then it rendered the corresponding view with the above details and the static details which is mentioned in the view

 We’ll discuss View in more detail in the next chapter. But for now just understand that Home Controller’s Index action is going to return the Index View under the Views  Home directory.
There is one more important point to notice here, that development box is running on the IIS Express.






Now, when you right-click on IIS Express you will see the currently running application on it and the random port which is allotted to it.








IIS Express is basically development version of Visual Studio which comes with Visual Studio 2012+ platform. It allocates random port for your website. In our case this is http://localhost:1033/.


Working with your 1st Controller:


Let’s get started by creating your 1st controller. This controller will simply search movies. Then, subsequently we’ll start adding some more features to the item displayed on the screen like when you click on the movie; corresponding movie details will flash on screen. However, it’s worth
time spending to understand the routing before jumping to write our 1st controller. Obviously, we’ll do deep dive about routing in routing chapter. But, 1st let’s understand few basic concepts of routing.


One of the core questions which you must be thinking that how ASP.Net MVC knows to load the index action when the URL http://localhost:1033/ is invoked, and the answer lies in the routing engine. The Routing Engine is the core concept of the ASP.Net MVC; it’s not coupled with
MVC Framework. Why am saying this, because we can use the routing engine to route the request for Web Forms, WCF Services etc. But, here in MVC we use this routing engine to redirect request to our controllers. In order to execute the same, we give the routing engine a map to follow using “MapRoute” API.


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



So, basically what a route map does, it provides a friendly name to the route, a pattern to follow
and default parameters for the route. So, if you think about the job of the routing engine, its job is pretty simple. Its job is to examine the URL and figure out where to send the request for processing. When, it examines the URL, it picks up the little pieces from the URL which tells the routing engine, where to send the request. In an MVC Application framework, we provide
nomenclature “Controller/Action/Id(somedata)”. So, if the routing engine doesn’t find the specific piece of data inside the URL, like controller name or action name, then it can use the default values assigned in the Map. In the above piece of code, it is “Home” controller and “Index” action are default values. Now, there are certain application level settings which are predefined in “Global.asax” file. This file is really interesting file in ASP.Net. It derives the application. Below is the sample code of this Global.asax file.





public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();


WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();



}
}


Here, you can see that this class is derived from http application and this allows us to drill into some application level events like “Application_Start”. So, this method will be processed by ASP.NET, before you process your 1st http request. So, it means when your application starts running, the code here will execute one time before any controllers start executing. So, this is the
place where in we put some configuration related changes for example Routing Configuration. 

The route configuration is done by 
“RouteConfig.RegisterRoutes(RouteTable.Routes)”. So,
here we are going to pass the routing table also known as “Global Routing Table”, values which contain all the routes for the entire application. This table will be empty initially, but when we call routes, it will add entries in the routing table. Now, let’s inspect the values inside the route
collection.  


public ActionResult Index()
{
var Controller = RouteData.Values["controller"];
var Action = RouteData.Values["action"];
var Id = RouteData.Values["id"];
string Output = string.Format("Controller = {0}, Action= {1}, Id= {2}",
Controller, Action, Id);
ViewBag.Message = Output;
return View();
}


Now, when I build the solution and run the app, it will produce me the below result



Now, if you see the above screen shot, it presented the Controller’s name and Action name. However, if you see that Id field is blank here, because while running the app, I have not invoked
the app with any parameters, hence Id field is blank. However, there are other ways as well to grab these values. We’ll see the same in some time.
Now, in this application I would like segregate my custom route with the default Route. So, let’s go to “RouteConfig.cs” file under “App_Start” folder. Here, am going to write my custom route.
However, before jumping directly to write a new route, let’s 1st understand, why it is required to write another one when already default route is there. Consider a scenario where in any user comes in and search for a movie say “Movie/Avatar”. In this case, Avatar will be treated as parameter name not like action method, so in this kind of scenario our default route won’t work
significantly. So, in order to fix the same I’ll write below route. Also, route placement is equally important. Because “Default Route” is very greedy, it matches almost any pattern. Note that route works on
the principle first match wins, so, it’s always suggested to place your new route in front of the default route. Also, as per MVC convention route name has to be unique. So, two routes cannot have the same name.


//Movie/Avatar
routes.MapRoute("Movie",
"Movie/{name}",
new { controller = "Movie", action = "Search", name = "" });
Now, with this new route in place, let’s build the app and try to navigate
(http://localhost:1033/Movie/Avatar) to the above mentioned URL and see the result.







Well, the above result was obvious; because I told to go and find out the “Movie Controller”, but since I have not created the movie controller yet, hence it presented me the 404 error. Now, let me go ahead and create my 1st controller. Right-Click the controller’s folder and say add new controller and then give the name as Movie Controller








Now, as you can see in the above screen shot I have added Movie Controller as an empty MVC controller. I took this liberty to write the entire code right from the scratch in front of you. So, the code for the same looks like as shown below. However, in the coming chapters we’ll learn the usage of other scaffolding techniques listed in the dropdown.







Now, here in the above screen shot as you can see that it created the default action method with the name “Index”. However, I have designed the route in such a way that it will look for “Search” action by default. Hence, let me go ahead and rename the Index action to Search action. Also,


instead of returning view for now I’ll just return Content so that I don’t have to create view necessarily and also my purpose is served






So, now when I build the page and refresh the same, it will simply return me content on the
browser.





passed in. However, there are couples of ways to fetch the route data from the URL, one way which I explained earlier in this chapter using the “RouteData” data structure and grab the value
for the same. However, MVC framework also provided simple way to address this problem and that is by using the parameter inside the action method.
So, if you add a parameter to this method, what MVC framework will do, it will go and look for the value that matches the parameter name and it return it to you. Basically, it will apply all the permutation and combination to find out the parameter value for you, it will search in the Route
data; it will also inspect the query string and in the form posted value. So, in this case


“/Movie/Avatar”, MVC framework will decide that I need a parameter with “UserInput”, and then this will get picked from the URL and that will get automatically passed in to me.





Here, as you can see in the above screenshot in order to sanitize the user input I have used

“Server.HtmlEncode”, this will simply convert any kind of malicious script in plain text. If I would have been returning the same in view, it could have been automatically taken care for me.
But, since I am returning the same with content view, hence I need to return the sanitized input to prevent any kind of scripting attack. Now, when I build and refresh the same, it will present me the below output.





You can also inspect the value for the same as well.






However, in the current scenario if I remove the parameter name and then invoke the URL that
will work fine as shown below.



Reason for this is the default value of the route, in the route I have mentioned “name=””” which means if nothing is getting passed in, then simply pass in the empty value as default parameter value. However, if I remove the name parameter from the route and then build and refresh the
page, then it will result me error as shown below.









So, in order to fix this I can go ahead and allow optional parameters for the parameter value as shown below




What this is doing that it just ensuring that even if the parameter didn’t mention in the url, it’s ok it will not result 404 error, it will just print out the empty result. Also, in order to prove the point that MVC framework looking for the parameter values at different locations; let me try one
example with query string.





We can also provide certain default values if nothing is passed in as parameter in the URL. In that case, it will simply return the default value on the screen as shown below.











 


No comments:

Post a Comment