When WebForms developers move to ASP.NET MVC, it looks like a whole new world. Today we look at some of the first questions that come up in an attempt to look at MVC from the WebForms Developer’s eyes. You may also want to check out my upcoming book with Pravin Dabade titled The Absolutely Awesome .NET Interview Book which contains plenty of questions for .NET Developers and Architects out there.
Question 1: Where are the Page_Load and the code behind? This separation of concerns thing is a little confusing how does it work?
To answer the first question directly, there is no Page_Load ‘event’ in ASP.NET MVC. Fact is there are no ‘Page’ events in MVC at all.
The MVC Pattern promotes separation of Model (data and logic), View (the HTML Page in case of ASP.NET MVC) and Controller (the glue between the View and Model) . To quote from my previous article - The MVC Pattern and ASP.NET MVC - Back to Basics we can define Model, View and Controller as follows:
Models: Classes that represent the problem domain (the problem/requirement we are trying to solve/accomplish). These classes also have code and logic to serialize and de-serialize the data into dedicated data stores as well as do validation and domain-specific logic. In ASP.NET MVC, this is the place for ORM or Data Access frameworks to do their magic.
Views: Views are essentially templates (cshtml or vbhtml files) used to generate the final HTML at runtime. Though, we say HTML, we could potentially return other types of Views like PDFs etc.
Controller: The class that manages the relationship between View and the Model. It is also responsible for accepting requests from the User and deciding which View to serve up if any.
This is different from WebForms where was intrinsically tied to the Controller that is the Code Behind. This resulted in mixing up responsibility of the View, the Controller (code to generate the HTML encapsulated in Server Side Controls) and the Model, often leading to strongly coupled implementation that were hard to extend. That said, you could write well-designed WebForms apps but you also had the additional responsibility of maintaining the discipline of separating concerns.
This article is published from the DotNetCurry .NET Magazine – A Free High Quality Digital Magazine for .NET professionals published once every two months. Subscribe to this eMagazine for Free and get access to hundreds of free tutorials from experts
Question 2: What's the fuss about Stateless nature of the web? Where did the ViewState go in ASP.NET MVC and how does data from the Web Page go to the Server now?
In all discussions involving MVC and WebForms you will hear how the Web is meant to be stateless. What it actually means is HTTP (the protocol over which Internet or the Web works) is a stateless protocol and it works on Requests from Clients to Server and Responses from server back to Clients. Beyond a Request/Response cycle, the server doesn’t know/care about the state of the client.
WebForms is an abstraction that was built on top of this, but it was primarily designed as an easy path for Developers from the Visual Basic world to migrate to the web world. So it mimicked things like Controls, events and event handlers and State. This implied there was a hidden overhead to maintain and transfer client state to the server every time some action was performed on client and handled on the server.
For example, if you were handling a TextChanged event on the server, it meant that the entire Page with its contents had to be sent to the server along with the information about this server call because Text on a particular control had changed. ASP.NET WebForms would then interpret this information and call the ‘text changed’ event handler to execute whatever code you had written for it. When the server side event handler returned, ASP.NET has to send back the exact same HTML that it had received along with the delta of whatever changes you made in the event handler.
All this overhead of information to manage state before and after the event handler is called, was all kept hidden from the developer, but was an overhead all the same. ViewState was one of the mechanisms used to manage the overhead.
In MVC, we no longer have this overhead or the server side eventing model. The only server ‘events’ are the HTTP calls of GET, POST, PUT, DELETE etc. It’s all the HTTP protocol level.
The following diagram that I borrowed from an earlier article makes things clearer
Looking at the Diagram left to right, top to bottom, the User is sitting at a browser and makes a request over HTTP that goes to the Web Server (hosting ASP.NET and ASP.NET MVC). Once the request reaches the server, it goes through the routing engine, to the controller, which interacts with the Model, invokes the view engine if required and returns a View. If the routing engine doesn’t find the URL that the user requested, it returns an error.
Instead of requesting a URL, if user was posting data from a HTML Form to the Server, then the browser (or custom AJAX) stuffs the form data into the Request body and packs it off to the server, which then does something called ModelBinding to create strongly typed Models of the data and send it to the Controller.
Each and every interaction between the User and the Web Application follows the same premise as above. No events, ViewState or any other overhead. This segues us into the next question.
Question 3: Where are my Rich Server side controls? Do I have to make-do with HTML Controls only? What’s this new Razor Syntax?
As WebForms developers, if you are already panicking about losing your favorite server controls, well, don’t panic, there are options for pretty much every server side control you have used. But to answer your question straight, there aren’t any ‘Server Side Controls’ so to speak in ASP.NET MVC. There are HtmlHelpers but their job is to make it easy to generate HTML on the server side, often using Model values etc. Since there is no ‘eventing’ per se, there are no ‘controls’. Whatever serverside parsing you do, end of the day, its plain old HTML that’s going to go to the user’s browser. Once on the browser, you can definitely use JavaScript frameworks and libraries to add richness to the interactivity.
Coming back to Razor Syntax, as we saw in the diagram earlier, the Controller after interacting with the Model may want to send back HTML Views. The templates for these Views are in respective cshtml files. View Engines interpret the cshtml in context of the Model and return plain HTML. There are multiple ViewEngines available in ASP.NET, each supporting a different server side templating language. The C# Razor engine looks for cshtml files that contain C# for templating, the VB.NET Razor engine looks for vbhtml files that contain VB.NET for templating. The ASPX engine is similar to the one used by WebForms and uses the <@ @> syntax for templating. Let’s look at an example of Razor Engine in action using C#.
Lets say we have the following controller
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View(new ScheduleTask());
}
[HttpPost]
public ActionResult Index(ScheduleTask task)
{
return View();
}
}
The Index() method is called when you do a HttpGet and the Index(ScheduleTask) method is called when data is posted to the server from the browser.
Let’s look at the HttpGet method, first, we’ll look at the post while answering the next question.
As we can see the Index() method is calling the View(…) method and passing on a Model object to it. For sake of simplicity it’s just a new object without much data.
Things to note here:
1. The View method will return a ViewResult which will in turn have the HTML that needs to be returned to the Browser.
2. Since no name is passed to the View method, it will assume the name of the View to be “Index.cshtml”. This is the convention that ASP.NET MVC follows.
So what does the Index.cshtml look like?
@model DateRangeValidator.Models.ScheduleTask
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
}
This is a quick peek as basic Razor Syntax
1. The first line declares the fact this view uses an instance of the ScheduleTask object.
2. The @using (Html.BeginForm()) section simply wraps the containing HTML with a