ASP.NET MVC 3 & the 14Four Template

An Introduction for Frontend Developers

Introduction to ASP.NET MVC

“ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and that gives you full control over markup for enjoyable, agile development. ASP.NET MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards.” – www.asp.net/mvc

ASP.NET MVC is an implementation of the MVC pattern, made popular in web development by Ruby on Rails, on top of the ASP.NET framework, allowing development with any programming language that works with .NET. It is a modern web development framework that allows cleaner separation between code, data, and presentation technology (HTML, etc), and also makes it easier to create cleaner and more standard-friendly markup. It builds on the base ASP.NET framework so previous experience doing WebForms development can fairly easily be applied to using MVC.

For anyone who isn’t aware, MVC stands for Model-View-Controller, which describes the basic separation of concerns. Models are usually objects which contain the data which the application processes, and in ASP.NET MVC are not directly tied to a specific technology/library, but can come from a large number of different data frameworks which are available on the .NET platform. Views are basically “templates” which contain the HTML and basic presentation-oriented logic which is executed on the server side to generate a page of HTML (or potentially XML/JSON/etc). Controllers are where all of the real action happens; the logic contained in the controllers is what responds to requests and gets data in the form of models and processes them and then determines what view to send back to the user. Controllers are basically the business logic. Also, as a separate piece of an application you will generally have support classes and such for utility functions and things of that nature.

As seen in Figure 1, the request flow in an ASP.NET MVC consists of the following (highly simplified) steps:

User requests a URL.

ASP.NET’s routing system evaluates the URL and compares it to user defined routing rules in order to determine what controller and what method (aka “action”) on that controller should process the request.

The controller action executes whatever business logic it needs to, which generally will include using some sort of data access layer to retrieve models from a database.

The controller then selects a view, passes it the models it needs to render the page, and then returns the view back to the MVC framework which then renders the view and sends the resulting data back to the user.

Request Data Flow

The Razor View Engine

ASP.NET MVC supports multiple view engines (or template engines if that makes more sense). The view engine is the part of the process that essentially combines the models and the template and renders out regular HTML code. Each view engine has its own syntax, each with its own benefits and drawbacks. Up until recently, there was only one official supported view engine provided by Microsoft with ASP.NET MVC, and it was the same system used by the original ASP.NET WebForms system and tended to be rather ugly with lots of extra characters breaking up the HTML code. However, Microsoft saw a need for an improved view engine that was “optimized around HTML generation using a code-focused templating approach” (Scott Guthrie, Corporate Vice President – Microsoft Developer Division).

This new view engine, dubbed “Razor”, provides a much more streamlined and efficient development process. It has a much smarter parser than the WebForms view engine and is able to more easily determine where code starts and ends automatically, thereby getting rid of a lot of extra clutter in the view file. Also, instead of designing a new language specifically for the logic in the templates, they decided to use regular .NET programming languages so developers can use their existing knowledge instead of having to learn something completely new. Because of these advances, Razor is very easy to learn and be productive with a minimum of effort.

Below are examples of a simple web page using the WebForms engine (first example), and the Razor engine (second):

WebForms Example

Razor Example

In both cases, the result of the view code above is the following:

Rendered View Result

As you can see, even with this very little example, the Razor syntax is much cleaner and more fluid. It is easy to transition from HTML code to C# view logic and back without a lot of extra characters cluttering up the code, especially when you start adding “if” statements and loops and things like that. All of these improvements prove to be even more valuable as the complexity of the view increases. When using the original WebForms view engine, having nested loops ended up being an extremely ugly mess of angle brackets and percent signs, whereas now with Razor we can keep things much cleaner and more readable, and more maintainable.

Razor “Layout” Pages

Razor also supports the concept of nested templates, through the use of “layout” pages. What you can do is setup high level templates which define the basic structure of every page, and then individual views just output their specific content in a region defined inside of the layout page. This way the site can have an easy to maintain and consistent structure across all of the pages for things like page container elements, navigation, footers, and such , and let each view focus only on the actual content needed to be rendered in that view.

The basics of the “Layout” pages are shown below. We have a simple master layout and then two separate views. The content in the views will be rendered into the layout page where you see the line “@RenderBody()”.

Main Layout File

Home View

About View

In the example above, the contents of the views, the “h2” tag and the “section” tag and all of their contents, will be rendered into the layout page at the location where the “@RenderBody()” call is.

I won’t show any examples here, but it is also possible to define layout “sections” in the layout page and in the views so each view could render its own content into the header or footer for example. It’s quite useful to have a section inside of the “head” tag so each view can add javascript files or css files if they need something not included in the main layout.

Layout pages can also be nested multiple levels deep, so you could have a main outer layout, and then have an inner layout for different sections of the site to define section specific sub navigation and such, and then have the individual views.

The 14Four ASP.NET MVC Template

The 14Four MVC Template is a continually evolving system which allows us to quickly build a wide range of dynamic websites by starting with a good base with a lot of the basic functionality which can be reused over many different sites. The goal is not to create a completely dynamic system like Drupal, ExpressionEngine, or anything of that sort, but rather to create a very efficient, scalable, and easy-to-use system that can easily be extended and modified by backend developers.

This template contains a lot of functionality that makes backend development much easier, but really doesn’t concern frontend developers at all so I’m only going to cover the basic file structure layout, and a few conventions that are being used so frontend developers can work with it more easily.

File Structure

Below is a screenshot of the basic development file structure of a site setup using our MVC template:

Root File Structure

It looks pretty complicated (and messy) initially, but all of the code files will get compiled into a single DLL file before deployment so a deployed or staged site will look much simpler. And all the frontend developer needs to be concerned about are the “assets” and “Views” directories.

The assets directory is pretty simple, it just contains folders for css files, images, javascript files and a few other items. The views directory is contains subfolders for each controller being used on the frontend (at least, if the controller needs to use any views), and also a “Shared” folder for layout pages and partial views (just small chunks of view code that can be rendered inside of views) and views that might be used with multiple controllers. In our MVC template, the main layout file is named “_Layout.cshtml” and is located in the “Shared” folder because it will be used (generally at least) by every other view on the frontend of the site. The rest of the views will be found in the other subfolders, and the names of the subfolders and views will most likely vary for each site.

A Few Frontend Technology Conventions

There are a couple of things that frontend developers need to be aware of, and preferably follow, when working with this template.

JavaScript should end in “.src.js” – We have tools that automatically minimize JavaScript files, and we have the ability to configure different environments to use either the source files or the minimized versions, but in order to make sure that we don’t bother minimizing files that shouldn’t be, we only minimize files that end in “.src.js”.

Use “LESS” files for CSS and leave CSS and LESS files at the same directory level – We have found that LESS is much nicer to work with than just straight up CSS so we use that, and like the JavaScript files mentioned above we have tools to automatically convert the LESS files to CSS and minified CSS files, and a system to configure whether the regular CSS or the minified CSS files are used. However, these systems work under the assumption that LESS and CSS and minified CSS files are all at the same level.

Conclusion

So, hopefully this has been an enlightening introduction/overview of ASP.NET MVC, and our specific template built on top of it, so any frontend developers who work with it will be able to jump in more quickly and easily. Obviously, we have barely scratched the surface of any sort of detailed look into it, so if you have any more questions and would like to know more about how things work then please come ask me.