Saturday, 4 June 2016

ASP.NET MVC Series: Article 5

Hello you all lovely people out there, presenting you guys with the 5th article in the MVC Series.
In this one, we will see as to how a particular View is selected to be rendered onto the browser, what exactly is a View, what are View Engines and stuffs.

Let's deep dive in.

View is a HTML page which is visible to the user, user sees it, does operations on the View, which then might generate a different View or else.

Views are HTML files with extension as .cshtml/.vbhtml, depending upon the programming language used to code (C#/VB.NET).

If we have a look at the Views directory in the MVC project, we will see there are various folders over there, as below:

Well, the folder names are in accordance with the Controller names, i.e. if we have 2 controllers with names as "HomeController" and "AccountController", we will have 2 folders in the Views directory with the names as "Home" and "Account".

In the above screenshot, we can see that we have one controller "HomeController", hence one folder in the Views directory with the name as "Home".

Also, we can see that we have a folder named as "Shared" in the Views directory, what does it do? Well, as the name implies, this "Shared" folder provides some shared views to the project. 

We can see that, we have "_Layout.cshtml" file, it basically gives a uniform layout to the all the views present in the project.

"Error.cshtml" is shown on the UI when there's an unhandled error or stuffs. 

We will talk about the "Shared" folder and its contents, in a great deal, in the later part of this article.

Let's concentrate on the "Home" views folder, we can see that there are multiple views in the folder, namely "About.cshtml", "Contact.cshtml", "Index.cshtml", where have they come from and why?

Well, individual views files conform to the individual action methods in a particular controller, i.e, we should have action methods as "About", "Contact", "Index" in the "HomeController".

When we look at the HomeController.cs file, we can see the below code which proves that there's a direct proportion between action methods and views.

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";
            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";
            return View();
        }
    }

Let's see the below code in detail:

public ActionResult Index()
        {
            return View();
        }

We are returning a View() and the return type is ActionResult, let's see as to what's the exact relation and how does the C# compiler understand the relationship between View() and ActionResult.

If we select the View(), and press F12 from the keyboard, we will see that we are taken to the definition, which says, 

        // Summary:
        //     Creates a System.Web.Mvc.ViewResult object that renders a view to the response.
        //
        // Returns:
        //     The System.Web.Mvc.Controller.View result that renders a view to the response.
        protected internal ViewResult View();

Let's again press F12 on ViewResult type, we will see that the definition is as below:

// Summary:
    //     Represents a class that is used to render a view by using an System.Web.Mvc.IView
    //     instance that is returned by an System.Web.Mvc.IViewEngine object.
    public class ViewResult : ViewResultBase

Let's again press F12 on ViewResultBase type, the definition which will come out will be as follows:

    // Summary:
    //     Represents a base class that is used to provide the model to the view and then
    //     render the view to the response.
    public abstract class ViewResultBase : ActionResult

We see that ViewResultBase type inherits from ActionResult, so ultimately View() inherits from ActionResult, and hence the code 

public ActionResult Index()
        {
            return View();
        }
compiles and works quite successfully.

A pictorial representation for more simplicity is given as below:


Let us try to add a new Action method and a new View, let's see what happens:

Go to the HomeController, and add the below code:

public ActionResult PlayFootball()
        {
            ViewBag.Message = "Euro 2016 coming up. Stay Tuned !!!";
            return View();
        }

Right click on the action method, and click "Add View", a pop-up will be opened by VS as below:


We will see that the View name textbox is pre-populated with the action method name as "PlayFootball", thus a direct relation between action method and view name.  

Let us try to retrieve the message from the action method in the view via the ViewBag dynamic object.


ViewBag is a mechanism via which we can transfer data from a controller to a view, we will study about it in detail later in the article.

Lets try to run the project and have a look at our newly created view, click on the Play Icon, the app will start under IIS Express, a random port will be assigned to the app, and we will see the view in the browser as below:


We see the route as "/Home/PlayFootball". The runtime goes to the "Home" directory in the Views folder, looks for "PlayFootball.cshtml", finds it and renders it onto the browser.

Let us now change the name of our view to "PlayFootball123.cshtml", and see what happens, how does the MVC engine react.

Let us browse to the earlier url as "http://localhost:16861/Home/PlayFootball", we get a yellow screen stating the below error:

Server Error in '/' Application.


The view 'PlayFootball' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/PlayFootball.aspx
~/Views/Home/PlayFootball.ascx
~/Views/Shared/PlayFootball.aspx
~/Views/Shared/PlayFootball.ascx
~/Views/Home/PlayFootball.cshtml
~/Views/Home/PlayFootball.vbhtml
~/Views/Shared/PlayFootball.cshtml
~/Views/Shared/PlayFootball.vbhtml

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The view 'PlayFootball' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/PlayFootball.aspx
~/Views/Home/PlayFootball.ascx
~/Views/Shared/PlayFootball.aspx
~/Views/Shared/PlayFootball.ascx
~/Views/Home/PlayFootball.cshtml
~/Views/Home/PlayFootball.vbhtml
~/Views/Shared/PlayFootball.cshtml
~/Views/Shared/PlayFootball.vbhtml


We are trying to browse to the "PlayFootball" view, but it doesn't exist at the moment, the MVC engine tries to find it in the Home folder first, it doesn't find it in Home, then it goes to the Shared folder, doesn't find it over there either. In the end, it provides us with the error that the view "PlayFootball" doesn't exist.

We see in the above error that the MVC engine searched for .aspx and .ascx files as well.

~/Views/Home/PlayFootball.aspx
~/Views/Home/PlayFootball.ascx

Where have these extensions come from? 

Well MVC supports 2 view engines by default, the ASPX view engine which was the default one in MVC 1 and MVC 2, and the Razor view engine which was launched with MVC3. 

Views with .aspx and .ascx used to be formed with the ASPX view engine, these views are given priority over the Razor views, i.e the .cshtml ones, hence the MVC engine searches for the .aspx views as well.

Till MVC 4 and VS 2012, we could have ASPX and Razor Views working simultaneously, but with VS 2013,  ASPX views did not fit well as per the StackOverflow post (http://stackoverflow.com/questions/19696842/using-aspx-view-engine-with-mvc-5).

I am still to explore ASPX views in VS 2015. If I get proper stuffs, I will write an article about it too.

This is it for this article guys, will be looking at Razor views, Layouts, Partial views, and the various mechanisms to pass in data from the controller to the view, in the next article.

Criticisms are most welcome. Till then see ya and stay tuned.

Tuesday, 31 May 2016

ASP.NET MVC Series: Article 4

Hello all lovely people out there, the 4th article in the series is here. Over here we will have a detailed look on Routing, how does MVC finds the correct action method, how to configure certain routes and more. 

In layman terms, Routing is nothing but the matching of the URL to a handler, which listens to the URL and acts on it.

In the traditional web forms scenario, the handler is a physical file, e.g an .aspx file.
In our MVC scenario, the handler is a class file which is basically a controller.

In fact, the above is one of the biggest difference between a web forms application and a MVC application, requests in a web forms app are mapped to the physical files present in the deployed folder, where as requests in a MVC app are mapped to class files.

Routing is not specific to MVC, in fact Routing feature is core to the ASP.NET framework, we can have routing enabled in a web forms app, a WCF service and so on.

ASP.NET MVC has popularized the concept of Routing.

So what exactly is a Route? 
As per MSDN, Route is a URL pattern which is mapped to a handler.
As discussed above, the handler in case of a Web Forms App is a physical file, where as in case of a MVC app, handler is a class file.

How do we define or create a Route?
Well, we define a route by creating a class an instance of the Route class, and passing in the desired URL pattern and a friendly route name.
Post that, we add this route to the Routes property of the RouteTable class, for the route to be active and working. 

Typically in a MVC app, in the RouteConfig.cs file, we see the below code:

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 }
            );
        }

    }

And in the Global.asax file, we see the below code:

        protected void Application_Start(){
           RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
In the static RegisterRoutes method, a new route with a friendly name as "Default" has been created, which is then added to the RouteTable object in the Application_Start() event of the Global.asax file. This ensures that the route is up and ready when the application starts.

This default route is created by VS itself when we create a MVC project, and obviously we can add our own custom routes as per the requirement, by calling the MapRoute extension method on the RouteCollection class.

Routes in a Web Forms application can be added by calling in the MapPageRoute() method on the RouteCollection class.

Let's discuss more on the URL patterns.
URL patterns consist of literals and placeholders. Placeholders are just like variables.

In MVC the general URL pattern is {controller}/{action}/{parameter}.
We see that we can have multiple placeholders in the pattern, but they have to be separated by a literal value. In the above pattern "/" is the literal value.

Let us try to test the above scenario, I have removed the "/" literal separating the {controller}/{action}, as below:


Let's try to browse by hitting on the play icon, we get the below yellow screen, which clearly says that 

A path segment cannot contain two consecutive parameters. They must be separated by a '/' or by a literal string.
Parameter name: routeUrl


Let's have a look as to how a route is selected and what happens behind the scenes, how is a particular action method of a particular controller executed. The detailed summary is as below:

  • When a request is received in MVC, it is first routed to the UrlRoutingModule object, this UrlRoutingModule object parses the incoming request and selects the first route which matches the incoming request. 
  • If the match is successful, the module retrieves the IRouteHandler object for the matched route. 
  • In MVC apps, the IRouteHandler object will be the instance of the MvcRouteHandler class.
  • The MvcRouteHandler instance creates a MvcHandler object. This MvcHandler typically implements IHttpHandler interface and is a HTTP Handler.
  • The MvcHandler determines which Controller to invoke, by looking at the {controller} placeholder of the URL and adding the suffix "Controller" to it. The {action} placeholder determines which action method to be executed.

The summary concludes this article, in the next one we will see as to how a View is selected and rendered, what rules and selection criterion are followed. Till then see ya and stay tuned.


Monday, 30 May 2016

ASP.NET MVC Series: Article 3

Hello all lovely people out there, this is the 3rd article in the series.

Over here, we will create a new MVC project via Visual Studio, and will see what VS brings for us in the project, what kind of files, extensions, markups etc are formed for us on the fly.

Let's jump in. Oh yeah, there are few pre-requisites to start with, most of you would be knowing them pretty much, but let me re-iterate them to be on the same page.

Pre-Requisites:
  • Presence of Visual Studio on the machine.In this series, we are going to concentrate on MVC5, hence presence of VS 2015, VS 2013, VS 2012 should be pretty okay.
  • Presence of SQL Server for database interactions. This article won't cover any thing related to databases at the moment, but the future articles will. Hence its better to have SQL server installed. I have plain old SQL Server 2008 R2 installed on my local machine.
The below snapshot shows the version of VS on my local machine. I have VS 2015 Community Edition.


Let's dive in, open your VS instance, click on File>New Project. Let's choose the .NET Framework version as 4.5 (although in VS 2015 currently there are versions greater than 4.5 as well), we will see that we have only one template as ASP.NET Web Application, because Microsoft is moving towards One ASP.NET. Click on that very template, give a project name, the directory details and click OK.


Select MVC template in the next screen from the ASP.NET 4.5 templates list, as shown below and click OK.


Change the authentication to "No Authentication" for the time being, click on OK, and voila your solution has been created by VS.:)

We can see that there are 2 projects in the solution, 1) Main MVC Project 2) Tests Project.

Let's have a look at the structure of the solution, the structure should look something as below:

SportsApp, the main MVC project has the following entities:
  • App_Data: Contains the application data files, may be Localdb, xml files, .mdf files etc.
  • App_Start: Contains the class files which are going to be executed once the application boots and starts. Will have BundleConfig.cs, FilterConfig.cs, RouteConfig.cs etc
  • Content: As the name implies, it contains the .css files for styles and stuffs 
  • Controllers: Contains class files for the controllers.
  • fonts: Contains files for fonts and stuffs, .svg, .woff files
  • Models: Class files for models
  • Scripts: Has multiple JavaScript files, jQuery, Bootstrap.js etc
  • Views: Contains different folders for different views as per the controller name, Views are files with .cshtml or .vbhtml extension
  • Global.asax: Has application level events
  • packages.config: List of all the Nuget packages available in the main MVC project
  • web.config: Application level configuration

SportsApp.Tests, the unit test project has:
  • Controllers: class files for test controllers
  • app.config: Configuration Settings for the Test project
  • packages.config: List of all the Nuget packages available in the test project
Let's try to run the project as it is. Click on the play icon on the menu bar, and let VS do its magic.


We will see that IIS Express gets started, the application runs on a random port, and we see the below page as the output on the browser.



Now, how does the above page appear as the output, where did all the beautiful content come from. These are the questions to be answered.

Well, MVC works on a concept called Routing. In the RouteConfig.cs class, we have a default route configured by VS, when we created the whole solution structure, something as below:


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 url pattern is : {controller}/{action}/{id}, but when we see the url of the output page, it is http://localhost:1686/, where there is no controller/action name, nor is there any id. Then how does it work?

The answer is, default values for the controller/action/id.
We can see in the above route that the default value for controller is "Home", for action it is "Index", where as id is an optional parameter, can be given or can be omitted.

As the application starts, the search for Index action method of the Home controller starts, the default application created in this scenario has that Index method in the Home Controller, as below:

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
   }

We can see that this very action method returns a View, so which view to return?

The search goes on for the Index view of the Home controller, we can see that in the Views folder, we have a folder named as Home, and we do have a view named as Index.cshtml.
When we open the Index.cshtml file, we can see that there's some html written, which gets rendered onto the browser.


This concludes the article, over here we have seen the basic skeleton of a MVC application, the default route of the application. We have also seen roughly, as to how the Index view was rendered.

The concept behind a view getting selected and rendered on the browser is little technical, we will see that in the next article in great detail. Till then see ya and stay tuned.

Saturday, 28 May 2016

ASP.NET MVC Series: Article 2

Hello all lovely people out there, here comes the second article in the series.

Here we are going to look into numerous versions of ASP.NET MVC, the cool features introduced along with the versions.

Microsoft has released 6 main versions of ASP.NET MVC, the latest being MVC 6.

Let's have a look at the various versions in a bulleted fashion:

ASP.NET MVC 1:
  • March 2009
  • MVC architecture with WebForms Engine
  • Routing
  • HTML Helpers
  • Unit Test Support

ASP.NET MVC 2:
  • March 2010
  • Support for partitioning large apps into AREAS
  • Strongly typed HTML helpers
  • Asynchronous Controllers Support
  • Support for rendering subsections of a page/site using Html.RenderAction
  • Attribute based model validation
  • Improved Visual Studio Tooling

ASP.NET MVC 3:
  • January 2011
  • RAZOR view engine: By far the most important update in MVC3
  • .NET 4 Data Annotations
  • Improved Model Validation
  • Global Action Filters
  • Better JavaScript support with unobtrusive JavaScript, jQuery Validation and JSON binding
  • Use of NuGet to manage dependencies

ASP.NET MVC 4:
  • August 2012
  • Introduction to ASP.NET Web API
  • Enhancements to default project templates
  • Mobile project template using jQuery Mobile
  • Display Modes
  • Task Support for Asynchronous controllers
  • Bundling and Minification

ASP.NET MVC 5:
  • October 2013
  • One ASP.NET
  • ASP.NET Identity
  • Bootstrap Templates
  • Attribute Routing
  • Authentication Filters
  • Filter overrides

ASP.NET MVC 6:

There are not a number of trustworthy articles which tell us about the features of MVC6, also at the time of this writing, there isn't a single book available on MVC 6.

Have read through MSDN links, and have found out the below broad features.
  • A lot of Dependency Injection.
  • Cross Platform (Can be run even on MAC, Linux)
  • Cloud Ready
  • Dependency on System.Web dll removed, instead Microsoft.AspNet.Mvc dll has to be used
  • Grunt, Bower, NPM support
  • Tag Helpers
  • Web API and MVC unified
Will add more features as I explore MVC 6 more.
In a nutshell, with the introduction with MVC 6, Microsoft is going towards the Open Source way in a rapid fashion, and I feel it was necessary too.
ASP.NET MVC code is available on Github and can be browsed and looked into (https://github.com/aspnet/Mvc).

This is it for this article, in the 3rd article, we will start with the coding and hands on part, we will create controllers, models, views, will perform database operations and stuffs. Stay tuned.