Table of contents

Introduction

Microsoft ASP.NET MVC framework follows a standard MVC pattern - the Model contains data that will be shown, the Controller performs actions when some event happens,
initializes the Model, and passes it to the View, and the View takes a Model and renders the HTML output that would be sent to the client browser. This architecture is shown
in the following figure:

The client (browser) sends an HTTP web request to the server-side. On the server we have controllers that handle
the request, takes data using the model,
and passes it to the view. The view generates HTML that should be sent back to client. In MVC 3, there are several view engines that can be used -
the standard ASP.NET
view engine, Razor, Spark, NHaml, etc. All of these view engines use different syntax for generating the view; however, they all work the same
way - the model is taken on the server-side, formatted using the template, and HTML is sent to the client browser.

This article introduces a different concept of the view engine - a client-side view engine that renders a view in a client browser.
In this concept, the model and the controller are still on the server-side. However, instead of the HTML, JSON is generated as an output from the server-side,
it is accepted on the client-side, and HTML is generated using the JavaScript templating engine. This architecture is shown
in the following figure:

Sending an HTTP request to the controller and handling the model is the same as in the standard method. However, instead of passing
the model object directly
to the server-side view, in this case, the model is sent to the client side formatted as a JSON object where it is processed by the client side view engine.

Background

This example shows how the client-side JavaScript template engine in the ASP.NET MVC project can be used instead of the standard server-side templating engines.
JavaScript templating engines use JSON objects as a model and generate HTML on the client side.
The principle of the JavaScript template engine is shown in the following figure:

With JavaScript template engines, you will need to pass the model object (usually some JavaScript object) to the view.
The view will have a template that defines
how this model object will be rendered. Once it binds the JavaScript model with the template, it will produce HTML as a standard server-side view engine.
As you can see, client-side templating engines work the same way as standard server-side MVC rendering engines. The only difference is that the views are processed in the browser.

Currently, there are several templating engines such as jsRender (successor of
the deprecated
jQuery template), Knockout,
Pure, noTemplate,
jsTemplate, Populate, and jTemplates, but this example
uses the jQuery loadJSON templating engine. The jQuery loadJSON
plug-in is a templating engine that binds a JSON object to a clean HTML template and generates
the view on the client-side. To bind the JavaScript model with a template
you will need to call something like the following line of code:

$("#template").loadJSON(model); //If you use loadJSON plugin
$("#template").render(model); //if you use jsRender plugin

This call will take the HTML fragment from the HTML in the current browser, and use it as a template for binding with
the JavaScript object (model).
As an example imagine that you have the following JSON object that should be placed in the template:

This is a simple JavaScript templating engine that has all the necessary features to implement an effective client-side templating engine,
however you have other ones too. As an example the same code generated using the jsrender template would be:

In the JavaScript you can see a very similar data structure. In the template are added placeholders that match the names of the properties surrounded
with {{: and }}. Also, here you have the ability to use for loops. In order to load
a model to the template you will need to use something like the following code:

$( "#view" ).html(
$( "#template" ).render( model )
);

As a result, an element with ID "view" will be populated with the HTML that is
a result of the merging model and the template.
The result will be like the one shown in the following example:

Although the loadJSON plug-in will be used in the examples, alternative implementation examples with Pure and jQuery template are shortly described in some sections.

Why are we using this architecture? There are a few benefits that come with this kind of architecture:

Performances - in this architecture, view processing is moved to the browser, where are used resources of the browser.
The server should return responses faster because there is no view processing on the server-side.

Throughput - in this architecture, instead of the HTML being returned a JSON object
is returned which is smaller than HTML because it does not contain unnecessary
tags that wrap pure information. JSON objects contain only data that should be shown
and they are loaded faster.

Caching - HTML templates that are used on the client side do not contain any data. Therefore they can be cached and reused for different view pages.
The only thing that changes is a JSON data that is loaded in the template.

Cross platform support - in this architecture, the same web server can support different platforms, from mobile devices to standard browsers, without
knowing who is the client. The server returns the same JSON data to all clients, and you can put different templates on the client side that will be
the best match
for the device resolution and supported features. As an example, on a mobile device, you can define
a smaller template where will not be shown rich UI elements,
while in a standard browser you will use a full rich-client UI.

In the following sections I will show you how to create a JSON based ASP.NET MVC application using client-site templating engines.

Using the code

In this article, a code example is presented which demonstrates how a client-side view engine can be used in ASP.NET MVC. The following sections show
how the jQuery loadJSON plug-in can be integrated into an ASP.NET MVC application in order to replace the standard server-side view engines.

Model

Two classes that contain information about companies and their employees are used as a model in this example. The source code of the Company/Employee model
classes is given in the following listing:

The Company class has two references to the Employee class, one to the single employee representing the manager and the array of employees for this company.

These model classes will be serialized in the controller and the JSON representation of the instances of the Company/Employee classes will
be provided to the view that is placed on the client-side.

Controller

The controller is not a standard controller that reacts on user action and returns the view as it works in standard server-side view engines. In the JavaScript
templating engines, the controller should return just a JSON object that will be used as the model on the client-side. This JSON object will be accepted
in the JavaScript templating function and the HTML output will be generated directly in the browser page. This example contains three pages: list of companies,
details about a company, and a form where company details can be edited. Hence, there are two action methods that should be implemented in the controller.
The first action returns a list of companies, and the second one returns a single company by ID (this action will be called when details are shown and when
a form with company data is populated). The source code for the controller is given in the following listing:

The Action methods take the model classes, format them as JSON results, and return the JSON to the view engine. The view engine on the client-side will
call these actions when the model is required by the view.

View

When a JavaScript templating engine is used, the view can be a static page. You can use standard .aspx pages as views but a plain HTML page can
be used as well. The given example has four view pages:

The list page where the list of companies is shown.

The details page where a single company's details are shown.

An edit page where information about a single company is loaded into a form where the details can be changed and posted to the server-side (although posting
the results is out of the scope of this article).

A hierarchy page where how the client-side template can be used to render complex nested structures is shown - this is the only example where the Employee class will be used.

These are typical cases of usage of the client pages. In the following sections, these view pages are described in detail and how the client-side engines
can be used to render them is explained.

Implementation

In this section I will show how you can implement standard list, details, and edit pages with jQuery templates.

List page

The list page is used to define a template that will be used to list the companies in the browser. A static view page is used in this example as shown in the following listing:

The li tag contains HTML elements whose class attributes match the properties in the model class.
The view is initialized using this JavaScript line from the heading:

$('li').loadJSON('/Company/List');

This line loads a JSON array from the /Company/List URL and loads it into the lI element. The Company/List URL activates
the List method in the Company controller which returns a list of companies formatted as a JSON array. When the loadJSON plug-in gets applied
on this element, properties of the objects are placed in the template. Moreover, this template item is replicated for each instance of the model in the array
that is bound to the template. As a result, a set of li elements will be created representing the list of companies that are loaded from
the /Company/List URL. Shown below is the generated view in the browser:

The jQuery loadJSON plug-in checks the type of HTML elements before it loads values in them. In most elements, the value will be placed as an inner text
of the element (e.g., SPAN, P, or DIV tags). However, if it finds a link element, instead of inner text, the plug-in adds
a property as an additional parameter in the URL placed in the href attribute. In the example above, the parameters ID=17, ID=18, ID=19, etc.,
are appended to the href attribute of the link. Therefore, to add a text of the link, you will need to place an additional SPAN tag
inside the link that will be loaded from the different property. You can find a live example of the list functionality
here.

In jQuery template, placeholders are names of properties
enclosed in ${ and } - in the example above, the ID, Name, and Address properties of the JSON objects
will be placed in the ${ID}, ${Name}, and ${Address} placeholders. The JavaScript code that should be used to load
JSON data in the template is shown below:

In the jQuery template, you need to take the template code placed in the unordered
list with an id "template", and compile it using a $.template()
method. The compiled template can be referenced by the name my_template when the view is generated. Then, an AJAX call is executed to load JSON from the /Populate/List URL
and data returned by this controller is bound to the template and set as the HTML code of the unordered list with an id "template".
The result of the template is the same as the result returned by the loadJSON plug-in - there is only a different syntax for the view and initialization code.

The jQuery template plug-in is now deprecated, no longer
in active development or maintenance. I would recommend to use jsRender instead. It has very similar sintax with minor changes. As an example in the jsRender instead of the ${ID} you are using:

{{:ID}} if you want to put raw value of data, or

{{>ID}} if you want to use HTML encoding.

Equivalent code that loads HTML from the template using the data returned via AJAX is shown in the following example:

As you can see it is very similar, so if you are already using jQuery template plugin and you want to convert your code to other template I would reccomend jsRender.

Details page

The Details page is used to show the details about a single company. It takes a JSON object from the /Company/Details page and loads the JSON object
in the HTML template. The Details page used in this example is shown in the listing below:

The page contains a definition of blank HTML templates with elements that have id attributes that match properties from the model.
The JavaScript call in the heading takes the ID parameter from the page URL and calls the /Company/Details server-side page with that parameter,
as shown in the following code example:

The controller action Details(int? ID) in CompanyController will be called when this URL is sent to the server, and a single company
will be returned as a JSON result. This JSON object will be loaded in the DIV with the "data" ID and elements
in that DIV will be populated. You can see a live example of the Details page here. An example of the generated view for one company in the sample project is shown in the figure below:

Alternative implementation using the Pure templating engine

Similar to the previous example, instead of loadJSON, any other templating engine can be used. As an example, if the Pure templating engine is used, the template can be the same as the one shown in the code sample (Pure uses the same clean
HTML code as loadJSON). The JavaScript initialization call is shown in the following example:

In the example above, an AJAX call that loads the JSON object from the /Home/Populate/<<id>> URL is performed, and in the callback function,
the JSON object is loaded into the div with ID 'data', as in the previous example. The second parameter of the Render
function is a directive that maps HTML elements to JSON properties. In the directive shown in the example above, the Name and Address
properties of the JSON object are loaded in the elements with ids Name and Address. In the alt attribute
of the element with id 'Logo' is loaded the Name, and in the src attribute of the element with ID
'Logo' is placed the Logo property of the JSON object. The advantage of Pure is that you can define custom mapping rules between elements,
their attributes, and properties of the JSON object. If you don't want to use directives, you can use the .autoRender() function instead
of .render(). The function .autoRender() is similar to the .loadJSON() function shown in the example above;
however, the .autoRender() function matches elements with properties by class name only (this is a "default directive" in the Pure templating engine).

Editing details

The Edit page is similar to the Details page. However, here, a single company record is loaded into the HTML form. An example of the Edit page is shown in the following listing:

The result of this call is a form populated with properties of the JSON object loaded from the /Company/Data/<ID> URL.
A live example of the form populated with the loadJSON plug-in can be found here and detailed rules that are used while populating the form are described
here.
An example of the form populated with JSON data is shown in the figure below:

The jQuery loadJSON plug-in will check the type of each form element where the JSON properties should be loaded, and depending on the type, it will
put the property as a text in text boxes and text areas, selected items in radio button groups, single, and multi selection lists, and checked/unchecked
state in check boxes. In other plug-ins, you would need to manually set the mapping rules for loading form elements.

In other plug-ins, I have not found an equivalent simple implementation of populating forms, so this example will not be shown in any alternative implementations.

Hierarchical view

The last view shows how the complex/hierarchical structures can be rendered using client-side engines. The previous examples used simple
structures (array of companies, single company), but as you might see in the model, there is a relation between Company and Employees.
When the list of companies is returned by the Company/List action, the following structure is returned as a JSON result:

As you can see, in the array of companies that is returned, for each company object, both simple properties (Name, Address, etc.)
and a nested object Manager and a nested array Employees are returned. Nested structures can also be displayed using client-side engines.

If loadJSON is used, the HTML template should have nested elements that match the structure of the returned JSON response. An example of an HTML
template that can be used with the loadJSON plug-in is shown in the listing below:

In the template are placed placeholders for the company fields (ID, Name, Address) as in the list example.
There is a placeholder Manager (in the SPAN tag) for the reference to the manager object that has two placeholders for the manager's
first name and last name. Also, there is a place holder for the Employees array in the DL tag where the array of Employee
objects associated to the company via the "Employee" array will be loaded. In that placeholder, nested placeholders for the first name
and last name of each employee that is returned in the nested array are placed. When a JSON object is loaded in this template using the loadJSON
function, a nested structure of the element (moved to the right side) is generated as shown in the following figure:

On the first level, companies in the ordered list are listed, where basic company details and the nested manager object are shown. For each company, a nested list
of the employees that work for the company is generated. In the screenshot above, employees for the first and fourth company are expanded while the others are collapsed.
You can see a live example here, but without buttons
for showing/hiding employees. The functionality for showing/hiding the nested lists of employees is implemented using custom JavaScript that is not part
of the templating engine - you can find more details about this script below.

Alternative implementation using the Pure templating engine

Instead of loadJSON, you can use any other templating engine. If you use Pure, the same HTML template can be used but you will need to define mapping rules
between the hierarchical template and the JSON object that is returned from the server-side. If Pure engine is used, the following script generates the view:

In this example, the JSON object is taken from the '/Company/List' URL and the returned JSON object is rendered into the OL element
that contains the template. The only difference is the directive that explicitly defines the mapping rules - I will try to explain the directive that is used
in this example. The Render function finds an li element and iterates over the array that is returned by the 'company<-' directive.
Each object in the loop will be identified as a 'company'. In the elements with classes ID and Address, the company.Name
and company.Address fields from the array are placed, and in the attribute href of the link with class "ID"
is placed the ID of the companies. In the elements with classes "FirstName" and "LastName" that are placed within
the element with class "Manager" are placed company.Manager.FirstName and company.Manager.LastName (properties of the nested object manager).

The inner list is generated using the last statement in the directive. In the DL element with class "Employees" is applied
a loop over the array company.Employees - each element in the loop is identified using the 'employee' identifier. In the elements DT
and DD with classes "FirstName" and "LastName" that are placed inside the DL element are placed the
employee.FirstName and employee.LastName properties of the JSON objects.

The Pure engine is a more powerful templating engine than the loadJSON plug-in because it has complex directives that enable you to customize mapping rules exactly how
you need them. However, as you can see, you will need to learn the syntax that is used for the directives to be able to customize the rendering rules. An explanation
of the syntax is not part of this article (this was just a specific example) so if you are interested in this, please find more details about the syntax
at the Pure site.

Applying custom JavaScript code

Note that the view engine gives you just a static HTML structure - if you need some interaction, you can add
a custom function to this structure.
As an example, in this view, functionality is added that opens and closes the nested employees list each time the user clicks on the image.
An example of the code for showing/hiding a nested list is shown in the following listing:

This code initially hides all the nested employees and attaches the click handler on the image where employees for the selected company are shown/hidden depending
on the state. This is completely independent of the template engine code, so the same functions can be used with different view engines as long as they generate
identical output. There are no constraints in this approach; as long as you know what structure you need, you can apply any JavaScript code on the structure
that is generated by the templating engine. Instead of the custom code, you can also apply some of the existing plug-ins that will continue to handle interaction with client.

As an example, if you need an expandable table, you can use the DataTables plugin that already handles most of the common functionalities you need. In this case, templating engines
can be used to generate the initial HTML structure required by the DataTables plug-in, and then you can apply this plug-in on the generated structure and let the plug-in handle all further custom interactions.

Conclusion

This article explains how the loadJSON plug-in can be used as a client-side templating engine, and it shows how JSON objects can be loaded directly in the HTML
elements on the client side. There are several benefits of using client-side templating engines:

Performance - loading JSON objects from the server side, only a minimal amount of data is transferred from the server to the client side. This way, it is not
required to load unnecessary HTML tags from the server and the time required to load data is shorter.

Caching - the example uses static HTML pages as views. Therefore, if active views (e.g., .aspx pages) are used instead, they can be cached on the server side.
This makes the server-side response time shorter.

True separation of design and code - using server-side templating engines, the code placed in the view is not completely clean. The HTML code contains some
elements that are required for binding server side data to the view elements. The examples in this article show that the view is completely clean - there is nothing
else except the HTML code in the view pages (not even custom attributes).

However, this is not a "Holy Grail" of web development as it does not resolve all your problems, nor does it represent the perfect solution.
If you have some complex logic you need to place in the view, e.g., determine whether some element should be disabled or hidden, or if you need to dynamically
show/hide some elements, you cannot implement this using simple client-side view engines. In such cases, it is better to retain server-side code data because
it will be easier to control it via code, partial views, and server-side controls. However, applying client-side view engines (when this is appropriate)
would bring you several benefits as explained above.

In this example, the loadJSON plug-in is used because it is the simplest plug-in that can be used and is the most appropriate for the presentation
of client-side view engine concepts. However, you can use any other templating engine and the approach will be similar. Other templating engines I recommend are:

jsRender - this is a successor of
the deprecated jQuery templates which were part of the standard jQuery API.

Pure - an excellent templating engine that provides a complex language for defining rules
for matching elements in the template with a JSON data source. The drawback of this engine is that you will need to learn the templating language used in directives
that define how data is bound to the template.

Knockout - the most advanced template I found with support for binding, change tracking/update of JSON model, etc. If you want full control with your template engine I would reccomend this one.

There is no best templating engine and each of the engines mentioned in this article have both advantages and disadvantages.
The major advantage of the loadJSON plug-in is its simplicity and ability to correctly populate form elements without specifying
any rules for mapping. However, the same thing can be achieved in other templating engines with more or less effort.

Share

About the Author

Graduated from Faculty of Electrical Engineering, Department of Computer Techniques and Informatics, University of Belgrade, Serbia.
Currently working in Microsoft as Program Manager on SQL Server product.
Member of JQuery community - created few popular plugins (four popular JQuery DataTables add-ins and loadJSON template engine).
Interests: Web and databases, Software engineering process(estimation and standardization), mobile and business intelligence platforms.