On this first day, we will understand why ASP.NET MVC over Webforms, Issues with Webforms and we will do two labs: one around controller and the other around views. We assess ASP.NET vs MVC vs WebForms, problems with ASP.NET Web Forms, understanding Controller and Views in ASP.NET MVC.
Contents
Complete Series
As the title promises, “Learn MVC step by step in 7 days”, so this article will have 7 articles, i.e., 1 article for each day. So start reading this tutorial series with a nice Monday and become a MVC guy till the end of the week.
Day 1 is kind of a warm up. On this first day, we will understand why ASP.NET MVC over Webforms? Issues with Webforms and we will do two Labs, one around controller and the other around views.
After each one of these labs, we will run through a small Q and A session where we will discuss concepts of the lab. So the structure of this article is Labs and then Q and A.
In case you have questions regarding any lab which are not answered in the Q and A, please feel free to put the same in the comment box below. We will definitely answer them and if we find those questions recurring, we will include the same in the article as well so that the rest of the community can benefit from the same.
So we just need 7 days from you and the rest this article assures you become an ASP.NET MVC developer.
We just need Visual Studio and the good news is that Visual Studio is completely free. You can download Visual Studio community edition from http://www.visualstudio.com/, there is no expiry, no license issues and you do not need deep pockets.
“You are reading this article because you know ASP.NET and you want to upgrade yourself to MVC.”
Sorry for the trouble, can you please read the above statement again and if you think it’s right, then this section is a must read for you.
Lot of ASP.NET developers who start MVC for the first time think that MVC is different, new, fresh from ASP.NET. But the truth is ASP.NET is a framework for creating a web application while MVC is a great architecture to organize and arrange our code in a better way. So rather than MVC, you can say ASP.NET MVC.
Ok so if the new thing is ASP.NET MVC, what is the old thing called as, it’s “ASP.NET Webforms”.
Let me correct your vocabulary:
“You are reading this article because you know ASP.NET Webforms and you want to upgrade yourself to ASP.NET MVC.”
So now that your vocabulary is corrected, welcome to the world of ASP.NET MVC and let’s start this tutorial.
ASP.NET Webforms has served and successfully delivered web application for the past 12 years. Let us try to understand the secret of what made Webforms so popular and successful.
If you see the success of Microsoft programming languages right from the days of VB (Visual Basic), it is due to RAD (Rapid Application Development) and visual programming approach. Visual programming was preached widely and was successful in Microsoft, hence they literally named their IDEs as “Visual Studio”.
By using Visual Studio, developers were able to drag drop UI elements on a designer area and at the backend , Visual Studio generates C# or VB.NET code for those elements. These codes were termed as “Behind Code” or “Code Behind”. In this code behind, developers can go and write logic to manipulate the UI elements.
So the visual RAD architecture of Microsoft has two things, one is the UI and the other is the code behind. So for ASP.NET WebForms, you have ASPX and ASPX.CS, for WPF, you have XAML / XAML.CS and so on.
So when ASP.NET Webform was so successful, why did Microsoft think about creating ASP.NET MVC. The main problem with ASP.NET Webform is performance, performance and performance. In web application, there are two aspects which define performance:
- Response time: How fast the server responds to request?
- Bandwidth consumption: How much data is sent?
Let us try to understand why response time is slower when it comes to ASP.NET Webforms. We did a small load testing experiment of Webform vs ASP.NET MVC and we found ASP.NET MVC to be twice faster.
Read more on how this test was done from here.
Let us try to understand why ASP.NET MVC was better in performance in the above load test. Consider the below simple UI code and code behind for that UI.
Assume the ASPX code has the below simple textbox
.
<asp:TextBox ID="TextBox1" runat="server">
In the code behind, you have written some logic which manipulates the textbox
values and the background
color.
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Text = "Make it simple";
TextBox1.BackColor = Color.Aqua;
}
When you run the above program, below is the HTML output.
If you see the HTML output by doing view source, it looks something as shown below:
<input name="TextBox1" type="text"
value="Make it simple" id="TextBox1"
style="background-color:Aqua;" />
Now stop reading for a moment, close your eyes and think. Try to get answers to the below questions:
- Is this an efficient way of generating HTML? Do we really need to make those long server trips to get that simple HTML on the browser ?.
- Can’t the developer write straightforward HTML, is it so tough?
If you see for every request, there is a conversion logic which runs and converts the server controls to HTML output. This conversion gets worse and heavy when we have grids, tree view controls, etc. where the HTML outputs are complicated HTML tables. Due to this unnecessary conversion, the response time get affected.
Solution for this problem: “GET RID of CODE BEHIND”, fold your sleeves and work with pure HTML.
Viewstate
has been a very dear and near friend of ASP.NET developers for the past 10 years because it automatically saves states between postbacks and reduces our development time. But this reduction in development time comes at a huge cost, viewstate increases the page size considerably. In this load test, we found viewstate
increases the page size twice as compared to ASP.NET MVC.
Below is the plot of the content length emitted from Webform and ASP.NET MVC.
The size increase is because of extra bytes generated from viewstate
, below is the snapshot of a viewstate
. Lot of people can argue that viewstate
can be disabled, but then we all know how developers are, if there is an option given, they would definitely try that out.
Solution for this problem: “GET RID of SERVER CONTROLS”.
Note: The rest of the three points down below are browny issues which have cropped up due to presence of code behind and server controls. But the main thing is always performance.
Now because we are slaves of the code behind and ASP.NET web server controls, we have “NO IDEA” what kind of HTML can come out and how efficient they are. For example, see the below ASPX code, can you guess what kind of HTML it will generate?
<asp:Label ID="Label1" runat="server" Text="I am label">
<asp:Literal ID="Literal1" runat="server" Text="I am a literal">
<asp:Panel ID="Panel1" runat="server">I am a panel
Will Label
generate DIV
tag or SPAN
tag ?. If you run the above code, below are the respective generated HTML. Label
generates a SPAN
, Literal
generates simple text, Panel
generates DIV
tag and so on.
<span id="Label1">I am label</span>
I am a literal
I am a panel
So rather than generating HTML using server controls, how about writing HTML directly and taking complete control of HTML.
So the solution for this problem is “DO NOT USE SERVER CONTROLS” and work with direct HTML.
The other great benefit of working directly with HTML is that your web designers can work very closely with the developer team. They can take the HTML code put in their favourite designer tool like dream weaver, front page, etc. and design independently. If we have server controls, these designer tools do not identify them easily.
If you watch any professional ASP.NET Webform project, you will notice that code behind class is where you have a huge amount of code and the code is really complicated. Now this code behind page class inherits from “System.Web.UI.Page
” class. This class is not a normal class which can be reused and instantiated anywhere. In other words, you can never do something as shown below for a Webform
class:
WebForm1 obj = new WebForm1();
obj.Button1_Click();
Because the “WebForm
” class cannot instantiate without “request
” and “response
” object. If you have ever seen the “ButtonClick
” events of “WebForm
”, they are as shown in the code below. From the code, you can know how difficult it is to instantiate the same.
protected void Button1_Click(object sender, EventArgs e)
{
// The logic which you want to reuse and invoke
}
Solution for this problem: “GET RID of SERVER CONTROLS and CODE BEHIND”.
As mentioned in the previous section, you cannot instantiate behind code straight forward, it’s very difficult to do unit testing or I will say automation testing on the code behind. Someone has to manually run the application and do the testing.
If we read the four issues mentioned in the previous section with ASP.NET Webforms, the main culprits are two things, “Code Behind” and “Server controls”. Below is the root cause diagram I have drawn. In this, I started with problems, what is the cause for it and the solution for the same. The complete diagram zeroes on two things “Code Behind” and “Server controls”.
The solution is we need to move the code behind to a separate simple class library and get rid of ASP.NET Server controls and write simple HTML.
In short, the solution should look something as shown in the below image:
As mentioned, the code behind and server controls are the root cause problem. So if you look at the current WebForm architecture which developers are using, it’s mostly three layer architecture. This three layer architecture comprises of UI which has ASPX and the CS code behind.
This UI talks with .NET classes which you can term as middle layer, business logic, etc. and the middle layer talks with data access layer.
So ASP.NET MVC comprises three sections - Model, View and Controller. The code behind logic goes into the controller. View is your ASPX, i.e., pure HTML and your Model is your middle layer. You can see in the above diagram how those layers fit in.
So if you see, there are two major changes VIEW becoming simple HTML and code behind moving to simple .NET classes termed as controller.
In ASP.NET MVC, request flow in general moves as follows:
Step 1: The first hit comes to the controller.
Step 2: Depending on the action, controller creates the object of the model. Model in turn calls the data access layer which fetches data in the model.
Step 3: This data filled model is then passed to the view for display purposes.
Now that we have understood the different components of ASP.NET MVC, let’s go in depth into each one of these components, let us start doing some labs. Let us first start with controllers as they are the most important and central part of the MVC architecture.
In order to understand Controller, first we need to understand this term User interaction logic.
Scenario 1
Did you ever give a thought to what happens when an end user hits a URL on a browser.
Browser sends request to server and server sends a response.
By means of such request, client is trying to interact with server. Server is able to respond back because some logic is written at server end to fulfil this request.
Some Logic?? So What Exactly Can Be This Logic?
Logic which will handle the user requests and user’s interaction with server. In short, User Interaction Logic.
Scenario 2
It's also possible that response sent by Server is an HTML response. HTML response which can consist of couple of input controls and a submit button.
What will happen when “Save Customer” button is clicked?
If your answer is “Some event handler will handle the button click”, then sorry :-(.
“In reality in web programming, there is no concept of events. In case of ASP.NET Web Forms, Microsoft wrote some code on behalf of us and brought us the feeling of event driven programming. It’s just an abstraction or the right word would illusion.”
When button is clicked, a simple HTTP request is sent to the server. This time the difference is, values in the “Customer Name”, “Address” and “Age” will be sent along with request. (In technical terms, “values are posted to the server”.) Ultimately, if it’s a request, then there must be a logic written in the server so that server can send back the response. In short, there must be some user interaction logic written on the server.
In ASP.NET MVC, the last letter C that is Controller is the one who will handle the user interaction Logic.
Step 1 – Create ASP.NET MVC 5 Project
Step 1.1 - Open Visual Studio 2013 (or higher). Click on File>>New>>Project.
Step 1.2 - Select Web Application. Put Name. Put Location and say OK.
Step 1.3 - Select MVC template.
Step 1.4 - Click on Change Authentication. Select “No Authentication” from “Change Authentication” dialog box and click OK.
Step 1.5 - Click OK.
Step 2 – Create Controller
Step 2.1 - In the solution explorer, right click the controller folder and select Add>>Controller.
Step 2.2 - Select “MVC 5 Controller – Empty” and click Add:
Step 2.3 - Put controller name as “TestController
” and click Add.
One very important point to note at this step is do not delete the word controller. For now, you can think it’s like a reserved keyword.
Step 3 - Create Action Method
Open newly created TestController
class. You will find a method inside it called “Index
”. Remove that method and add new public
method called “GetString
” as follows:
public class TestController : Controller
{
public string GetString()
{
return "Hello World is old now. It’s time for wassup bro ;)";
}
}
Step 4 - Execute and Test
Press F5. In the address bar, put “ControllerName/ActionName” as follows. Please note do not type the word “Controller” just type “Test”.
TestController
is the class name whereas Test
is the controller name. Please note when you type the controller name on the URL, it should be without the word controller.
ASP.NET MVC follows Convention based approach. It strictly looks into the conventions we used.
In ASP.NET MVC, two things are very important:
- How we name something?
- Where we keep something?
Action
method is simply a public
method inside controller which accepts user’s request and returns some response. In the above example, action
method “GetString
” is returning a string
response type.
Note: In ASP.NET Web Forms, default return response is always HTML. In case we want to return something other than HTML (in ASP.NET Web Forms), we create HTTP handlers, override content type, do response.end
, etc. It’s not an easy task. In ASP.NET MVC, it’s very easy. If return type is ‘string
’, you can just return string
:-) , you do not need to send complete HTML.
Look at the following code block:
namespace WebApplication1.Controllers
{
public class Customer
{
public string CustomerName { get; set; }
public string Address { get; set; }
}
public class TestController : Controller
{
public Customer GetCustomer()
{
Customer c = new Customer();
c.CustomerName = "Customer 1";
c.Address = "Address1";
return c;
}
}
}
Output of the above action method will look as shown below:
When return type is some object like ‘customer
’, it will return ‘ToString()
’ implementation of that object. By default ‘ToString()
’ method returns fully qualified name of the class which is “NameSpace.ClassName
”.
Simply override “ToString
” method of class as follows:
public override string ToString()
{
return this.CustomerName+"|"+this.Address;
}
Press F5. Output will be as follows:
Yes, every public
method will become action methods automatically.
They are simply methods of a class and not available publicly . In simple words, these methods cannot be invoked from the web.
Simply decorate it with NonAction
attribute as follows:
[NonAction]
public string SimpleMethod()
{
return "Hi, I am not action method";
}
When we try to make a request to the above action method, we will get the following response:
As we discussed earlier, controller will handle the user’s requests and send the response. Most commonly, the response is HTML as browser understands that format much better. HTML with some images, texts, Input controls, etc. Normally in the technical world layer, defining the user interface design is termed as UI layer and in ASP.NET MVC, it is termed as View.
In the first lab, we created a simple MVC application with just controller and simple string
return type. Let us go and add view part to the MVC application.
Step 1 – Create New Action Method
Add a new action method inside TestController
as follows:
public ActionResult GetView()
{
return View("MyView");
}
Step 2 – Create View
Step 2.1. Right click the above action method and select “Add View”.
Step 2.2. In the “Add View
” dialog box, put view name as “MyView
”, uncheck “use a layout” checkbox and click “Add”.
It will add a new view inside “Views/Test” folder in Solution Explorer.
Step 3 – Add Contents to View
Open MyView.cshtml file and add contents as follows:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>MyView</title>
</head>
<body>
<div>Welcome to MVC 5 Step by Step learning.</div>
</body>
</html>
Step 4 - Test and Execute
Press F5 and execute the application.
In ASP.NET MVC, Views associated with the particular controller is placed inside a special folder. This special folder will be named as “ControllerName
” and placed inside Views folder (located in the root folder). For every controller, only those views will be available which are located inside its own folder.
For example: All the views related to Test controller will be placed inside “~/Views/Test” and Test controller can access only those views which are inside Test folder.
Yes, we can. For that, we will keep those files inside a special folder called “Shared”.
Views located inside this Shared folder will be available to all the controllers.
Yes. Look at the following code:
public ActionResult GetView()
{
if(Some_Condition_Is_Matching)
{
return View("MyView");
}
else
{
return View("YourView");
}
}
Note: In ASP.NET, MVC views and controllers are not tightly coupled. One action method can refer to more than one view and one view can be referred by more than one action method (by keeping them in Shared folder). It provides better reusability.
Creates ViewResult
object which renders View
to the response.
ViewResult
internally creates the object of ViewPageActivator
. ViewResult
chooses the correct ViewEngine
and passes ViewPageActivator
object as argument to ViewEngine
’s constructor. ViewEngine
creates the object of View
class. ViewResult
invokes the RenderView
method of View
.
Note: We have a separate topic in the series discussing ASP.NET MVC life cycle in detail.
ActionResult
is the abstract
class whereas ViewResult
is the multi level child of ActionResult
. Multilevel
because, ViewResult
is the child of ViewResultBase
and ViewResultBase
is the child of ActionResult
.
To achieve polymorphism. Look at the following example:
public ActionResult GetView()
{
if(Some_Condition_Is_Matching)
{
return View("MyView");
}
else
{
return Content("Hi Welcome");
}
}
In the above example, when some condition is matching, we are returning we are invoking “View
” function which will return ViewResult
whereas in some other condition, we are invoking “Content
” function which is returning Content Result.
ViewResult
represents a complete HTML response whereas ContentResult
represents a scalar text response. It’s just like returning pure string
. Difference is ContentResult
is an ActionResult
wrapper around string
result. ContentResult
is also the child of ActionResult
.
Yes, then it will find the view with name “CurrentActionName
”.
On day 2, we will talk about Models, Validation, Jquery and Json. So keep rocking, keep learning.
Both of us, authors, have started an initiative Learn MVC in 2 days, i.e., Flat 16 hours. Below is the video for the same.
For further reading, do watch the below interview preparation videos and step by step video series.
History
- 17th January, 2015: Initial version