Contents
Pre-requisite
Introduction
ASP.NET Webform behind code –boon and curse
Problem 1 :- View based solution for Action based requirement
Problem 2:- Side effects of bad architecture: - Tight coupling
Problem 3:- HTML is not the only response type
Problem 4:- FlexibleCombination of view and data
Problem 5:- Making behind code a normal class for unit testing
So the solution is MVC?
What do we loose ?
Request from a DAD
Thanks to Sanjana my daughter to create the above image. I would be thankful if you can share this image from FB https://www.facebook.com/photo.php?fbid=685327044884788 which would boost her in becoming a cartoonist ahead. I want to just inform her how good she is in drawing and should think about it as career path.
BTW The above image will help you to visualize why MVC is better than webforms. As you read this Learn MVC step by step article ahead this image will help you to connect things together.
In this article I would be using two terminologies which will be used very frequently ASP.NET Web forms and ASP.NET MVC. Many developers think that ASP.NET is different from MVC. But the fact is MVC is an architecture coding style and ASP.NET a framework. If you are from the category who think ASP.NET is different from MVC then my honest suggestion is to first read this article to avoid any further confusion http://computerauthor.blogspot.in/2014/08/aspnet-vs-mvc-vocabulary-confusion_15.html
If you watch the recent Microsoft agenda you will clearly see they are focusing on MVC , MVC and MVC. So the question is why is Microsoft so keen to dump a successful thing like ASP.NET Webform and persuade the Microsoft web development community to use ASP.NET MVC.
That’s what this article will focus on.
If you closely watch ASP.NET webform technology it’s a RAD / VISUAL approach for web development. In other words developers drag and drop user controls on the designer and the VS tool codes in the behind code.
So in other words when you drag and drop a button control on the designer a button object is created and developers can write code in the click event of the button object.
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
}
}
So when developers drag and drop these UI elements, double click to get the events on the front end, write logic in those events etc. At the back end smartly and quietly Microsoft code’s logic in the ASPX.CS partial class file.
Now this partial behind code file was the key to success for delivering ASP.NET Webformprojects faster as developers where encapsulated from lot of technical details like events, delegates, HTTP protocol POST,GET, session management etc. You would probably like to read this article why Microsoft has partial classes ?and Microsoft UI success story.
But due to the way the behind code was positioned and invoked it has 5 serious problems. So let’s discuss those 5 problems and how MVC helps to address the same.
Websites at the end of the day are used by end users. End users come with a specific purpose to a website and they communicate their purpose by actions. For instance if somebody comes to shop on a shopping portal he will communicate his purposeusing actions like:-
- Buy product.
- Print invoice
Now these actions are communicated by button click , right click or through a browser URL etc. Due to this action based structure HTTP protocol was chosen for Web because it had actions like POST,GET,PUT,DELETEetc which can communicate the purpose of end users more clearly. That also makes REST a popular way of addressing end user request. So logically if we can map these actions to methods / functions of our program that would make more sense and also keep the architecture simple.
But Microsoft had no way out, they wanted to support RAD concept or we can term it as visual programming concept, so they ended up with a view based solution for an action based structure.
So flow of request went something WEIRD like this for web forms( for visual’s see the above diagram):-
- End user sends a request with action like HTTP POST / GET etc.
- IIS webserver maps this request to a view.
- View invokes the page life cycle, walks through events and then INVOKES THE APPROPRIATE ACTION.
- Finally action put’s the RESULT IN HTML format and sends it to the end user browser.
Microsoft ended with a view based architecture for an action based requirement. So the architecture itself was not fitting logically to the end user’s action based approach. In other words if the end user sends a “Buy” action it first comes to a view like “Shopping.aspx” who in turn kicks of “Shopping.aspx.cs” which executes a complicated page life cycle which in turn executes the action which will fulfill the request of the end user.
This is like hitting the bush. The end requests aregetting mapped to the actual action after a complicated page life cycle is completed. So how about we make itan action oriented architecturerather thanview oriented. Or I can rephrase it “HOW CAN WE MAKE ACTION FIRST STRUCTURE RATHER THAN A VIEW FIRST STRUCTURE ?”.
So how about hitting the action first and then the action picks up view. This would make the flow more logical and clear. That’s what exactly MVC architecture does. The first hit comes to an action which belongs in to a controller and then controller invokes the view with appropriate model.
Once you start with a wrong architecture you end up adjusting things and then you end up with serious side effects. In this case the same was happening. The behind code which looks physically different in different files was never actually decoupled i.e. ASPX.CS cannot be separated from ASPX.
In simple words I cannot attach “Customer.aspx.cs” with “CustomerDetailed.aspx” easily. The behind code is tightly coupled with view. It is not reusable.
If you ever analyze the quantity of behind code w.r.t to other layers of the project it’s huge in size with complex events. This makes the code unreadable and difficult to maintain from long term perspective.
So if we can change the view first based architecture to action first based architecture then we can reuse the same action code with different views. For instance if an end user sends an action “Display” it can invoke “DisplayDesktop.aspx” or it can display “DisplayMobile.aspx” depending on the type of device.
So in the MVC action depending on situation we can invoke “MobileView” or “NormalView” , below is the sample code for the same. Now imagining achieving this in behind code of the Webform , difficult very difficult right.
public ActionResult Index(string DeviceType)
{
if (viewType == "Mobile")
{
return View("MobileView");
}
else
{
return View("NormalView");
}
}
Because of the tight coupling between view and code behind even the response type is fixed in webform , its by default HTML. If you wish to change it you need to play around with Content-type and “Response.End” methods etc which is quiet tedious.
If we create “Action” first structure then the action has all the luxury in the world to decide what kind of response type should go out. This makes our system more flexible in terms of same action with different outputs.
Below is a simple MVC action code which send’s JSON or HTML result depending on the value passed to the action. This kind of flexibility is difficult to achieve with webformview’s because they are meant to emit only HTML.
public ActionResult Index(string viewType)
{
if (viewType == "JSON")
{
return Json(new Customer(), JsonRequestBehavior.AllowGet);
}
else
{
return View("DisplayCustomer", new Customer());
}
}
When we send response to a user it’s a combination of view (display) and data (model).Webform is a view first architecture so the view decides which model to connect making the view NOT SO flexible and also involving view in complex decision making. That clearly violates SRP of the SOLID principle read here more about SOLID Principles.
But if we make action first architecture then the first hits comes to the action and he picks the Model and the view to send different responses.
In MVC action you can code something as shown below. You can pick up the same model and attach it with different view. For example in the below code we have taken “customerdata” model and attached with “DetailCustomer” view and the same model in other situation is attached with “Customer” view.
public ActionResult Index(string ViewName,Customer customerdata)
{
if (ViewName == "Detailed")
{
return View("DetailCustomer",customerdata);
}
else
{
return View("Customer",customerdata);
}
}
This kind of flexibility to achieve through Webform is very difficult because the invocation comes on the view itself and then you need write all decision making logic in the page life cycle and redirect to some other view not making the implementation so clean.
The behind code in webform is a very typical heavy and bulky weight partial class which cannot be instantiated in simple C# code straightforward. Remember the Webform screen inherits from the “Page” class. This page class cannot be created directly as it has lot of dependencies.
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void Button1_Click(object sender, EventArgs e)
{
Session["SomeSession"] = "Is this set";
}
}
Now the next thing which would come to your mind why would you want this page class to be instantiated. One of the place where I would like this page class to be instantiated is for unit testing. I would like to invoke the actions of the button click methods and test if the session variables are set properly,view states are properly etc.
But if you ever try to do that like as shown in the below code you will end with weird code as shown below. Watch out those ugly event args passed to the button click methods.
[TestMethod]
public void TestMethod1()
{
WebApplication22.WebForm1 obj = new WebApplication22.WebForm1();
obj.Button1_Click(this, new EventArgs());
}
And when you invoke it asks for more things which makes the UI Unit testing impossible.
In case of MVC this becomes a normal class. A class which can instantiated in simple unit test project and you can test various aspects like session ,viewbag , tempdata in an easy way.
public class HomeController : Controller
{
public ActionResult Index()
{
Session["SomeSession"] = "Is this set";
return View("SomeView");
}
}
So to change from a view based architecture to an action based MVC architecture we need to do the following structural changes ( The above image gives a visual view of the same):-
- Move the behind code in to a controller class with all the events converted in to methods which can be termed as actions.
- The middle layer becomes the model which provides data and business logic.
- The view just does display,positioning and layouting.
- The DAL and other layers do not change a lot as they have no connection with the behind code issue directly.
So with MVC architecture we have the below three step flow:-
- End user sends his request application. Application routes the request to the Controller. Controller is a logical entity which groups actions together.
- Controller maps that request to a particular action.
- Now action has two tasks to do first it needs to access appropriate data depending on the action and second that data has to be connected to the proper view. Action creates the model object and connects the model to the view to send the final response.
The biggest advantage of ASP.NET WebForm is RAD / VISUAL programming. Even though it’s a quick and dirty way of doing things it helps you to complete applications faster, make your clients happy and deliver on time. You can read this article which talks about what you will miss in MVC http://www.codeproject.com/Articles/808297/Things-you-will-miss-in-ASP-NET-MVC-as-an-ASP-NET
The decision of Webforms was the right way for Microsoft in year 2000 because it wanted to migrate the VB6 , VF , VC++ developers whom they had addicted to RAD programming. I think Webform has achieved its goal for what it was created for now it’s time move toward’s better and logical architecture i.e. MVC .
So if you are convinced that MVC is the way forward you can Learn MVC in 2 days i.e. 16 hours using the below video.
For further reading do watch the below interview preparation videos and step by step video series.
Also read and learn from Web Form vs MVC article.