Approximately ten years ago, Microsoft introduced ASP.NET — a framework for building web applications using the new .NET platform. ASP.NET was designed to assist developers to build, deploy, and maintain web pages and websites. ASP.NET integrates with Microsoft Internet Information Server (IIS) and provides developers with a rich set of tools to develop dynamic web applications.
When it was introduced, this framework focused on Web Forms. Web Forms abstracted away many of the low-level complexities of HTML and HTTP, giving developers an experience similar to one used to build Windows Forms. By using Web Forms, developers could quickly create an interactive web page, even if they knew little about the underlying technologies of the web. This development experience was similar to the popular Visual Basic language, so it appealed to developers familiar with that language.
Like its predecessor Active Server Pages (ASP), ASP.NET provides a developer with the ability to build web applications using a combination of code and markup. Unlike the classic ASP, ASP.NET is built on top of the Common Language Runtime (CLR) and uses the power of .NET. Because of this, ASP.NET can take advantage of CLR benefits, such as automatic garbage collection, a rich set of libraries, and a robust security model.
The latest version of ASP.NET includes enhancements to the ASP.NET Web Forms Framework and an updated version of the new ASP.NET Model-View-Controller (MVC) framework. Visual Studio .NET 2010 is also the first version to ship with jQuery libraries, which enable developers to build rich client-side functionality into their websites.
This article focuses on what is new in ASP.NET 4. First, you learn about some of the new features and enhancements of ASP.NET 4 Web Forms. Finally, this article covers how to effectively use jQuery to enhance your application. Along the way, a sample application provides guidance on how to implement these new features
UNDERSTANDING WEB FORMS
The Web Forms Framework was introduced with ASP.NET 1.0. Countless websites have been successfully built and deployed using this platform.
Essentially, the Web Forms Framework was designed to abstract away the complexities of Hypertext Markup Language (HTML) and Hypertext Transfer Protocol (HTTP) to make web development feel more like Visual Basic forms development. Following are characteristics of Web Forms application development:
· The developer is presented with a design surface that looks like a web page.
· Web controls are dragged onto this design surface.
· Properties are set on the page and on the controls.
· Code is written to manipulate the page, controls, and associated data.
Using Visual Studio, developers can quickly build a web application. A rich set of built-in controls and third-party controls adds to this abstraction and helps cut down on many development tasks. However, this rapid application development (RAD) comes at a cost. Web Forms and associated controls automatically generate HTML and JavaScript. Sometimes the generated code does not exactly match your needs. To add to the difficulty, different web browsers often render the same HTML in different ways, and understand JavaScript differently — particularly as JavaScript interacts with the web page’s Document Object Model (DOM). A common problem is that a page renders properly in one browser but improperly in another.
Using Web Forms, it is difficult to modify the output HTML or JavaScript. This is especially an issue when you target multiple browsers. If you have trouble tweaking HTML, you will have trouble supporting some browsers. For this reason, web developers should learn as much as they can about HTML, Cascading Style Sheets (CSS), and HTTP. Abstractions such as Web Forms are fine, but they do not excuse the responsibility to understand the technologies they abstract.
Microsoft introduced a number of enhancements to ASP.NET with version 4. Following are a few of the most important ones:
· Improved handling of View State provides users with greater fl exibility over the controls
that participate in View State.
· The web.config file has been greatly simplified.
· A new Web Project template provides greater functionality.
· web.config transformations make it easier to deploy to a new environment.
Let’s take a look at these in a bit more detail.
View State
By default, the web and its underlying transport protocol (HTTP) are stateless. This means that, by default, each request remembers nothing about any previous request. ASP.NET introduced View State as a way to maintain state between pages in a web application. View State works by automatically creating an extra, hidden input within an HTML form. To save the state of the submitted fields on a page, ASP.NET encodes View State data into a single string and sets the value of this hidden field to that string. This field is created on the server and sent down to the client with the rest of the web page. This convenience comes at a price. The encoded data is submitted each time the form is submitted and it is returned to the browser with each response. If you have a lot of data stored in ViewState that data can get quite large, slowing down communication between the client and the server.
Using a previous version of ASP.NET, a developer could turn View State on or off at the page level, or at the control level. Prior to ASP.NET 4, you basically had three options for enabling View State:
· Turn off View State for the entire page — If you do this, you do not realize any of the benefits of View State.
· Turn on View State for the entire page — If you do this, you may encode and add unneeded
items to View State, bloating the payload sent between the server and the browser, slowing
your application, and degrading the user experience.
· Turn on View State for the page, and then disable View State for controls that do not
need it — This strategy works well if you want View State for almost every control on the
page, but not for a few controls. It can be a real pain if you want View State enabled only
for a couple controls.
ASP.NET 4 provides two relevant properties to control View State: ViewStateMode and EnableViewState. Only ViewStateMode is new in version 4, but the two properties work together. EnableViewState has been around since the first version of ASP.NET. It can be set for an entire page, or for a single control, and it can be set to either True or False. EnableViewState does not turn on View State for any controls. Rather, it determines whether View State may be turned on for a control, and for any controls below it in the control containership hierarchy. A control’s ViewStateMode turns on or off View State, but only if EnableViewState is True. ViewStateMode can be enabled or disabled explicitly, or by inheriting this property from its parent container. Setting a Page or Control’s View State attribute to False disables View State for that Page/ Control and for any controls contained therein.
In previous versions of ASP.NET, the only way to selectively enable and disable View State on controls
was to set EnableViewState=”True” on the page, and set EnableViewState=”False” on the controls for which you did not want to maintain the overhead of passing View State between the
client and the server.
You can set ViewStateMode as an attribute of a page or control, or you can set it in code. Following are the allowable values:
· Enabled — Turns on View State for a control.
· Disabled — Turns off View State for a control.
· Inherit — Tells ASP.NET to set the ViewStateMode to that of the control’s parent container.
This is the default value for a user control.
ViewStateMode is only relevant if EnableViewState is set to True for a control or the control’s parent. If EnableViewState is True, ViewStateMode turns View State on or off for a given control. By turning on View State, any data associated with a control is encoded on the server, saved with a hidden input field, and rendered to the client, so it will be submitted the next time the form is submitted.
My recommendation is to set EnableViewState to True on the page and to selectively turn on (set
to Enabled) ViewStateMode for the controls that will benefit from it. This minimizes the payload sent between the client and server and prevents you from accidentally adding to this payload as you add new controls to the page. Following is an example of this:
<%@ Page …
EnableViewState=”True” ViewStateMode=”Disabled” %>
<asp:Label runat=”server” Text=”Enter UserName:” ID=”EnterUserNameLabel” />
<br />
<asp:TextBox runat=”server” ID=”UserName” ViewStateMode=”true” />
web.config Transformations
One of the challenges of application development is migrating configuration files from one environment
to another. I typically develop my applications in a Development environment, using a Development database, Development web services, and the files on my own computer. Many of these settings (such as connection strings, file paths, and URLs) are set in the application’s web.config file.
At some point, I deploy my application to a Test environment, so that testers can try it out. The Test environment can use different connection strings, URLs, and file paths, so I need to modify the web .config at the time I deploy the application to this environment. This problem presents itself again when I deploy to a Staging environment, a Production environment, and any other environment my organization or customer uses.
ASP.NET 4 provides an elegant way to handle modifying a web.config file as the application is deployed to different environments. Using Transformations, you can create a base web.config file and a separate file for each of your environments. Each environment file contains only those elements that vary from the base configuration.
Simplified web.config
In earlier versions of ASP.NET, the web.config file tended to become bloated and difficult to manage.
Even a newly created empty web project contained a large web.config file. With ASP.NET 4, much of the default configuration has been moved to the machine.config file, making the web.config much smaller. You can even create an ASP.NET application with no settings in the web.config file. Developers are encouraged to add only those settings specific to the application to which the web.config file applies.
A smaller web.config file makes configuration settings easier to find and to manage.
New ASP.NET Web Forms Templates
Visual Studio 2010 includes a new and improved web template that is designed to get web developers up and running faster. You can find the ASP.NET Web Application template in the New Project dialog under Installed Templates Í Web, as shown in Figure 1-1. From the Visual Studio menu, select File Í New Project to open this dialog.
FIGURE 1-1: Locating the ASP.NET Web Application template
This template creates an application that includes Home and About pages, and pages for managing users and roles. The site uses a default stylesheet and master page, giving it a polished look; but developers can modify these files to meet their needs. The application is ready to run and use as soon as it is created. You can add forms and code to the initial site to suit the specific needs of your application. Figure 1-2 shows the structure of an ASP.NET Web Application project as viewed from Solution Explorer.
FIGURE 1-2: Structure of an ASP.NET Web Application project
The ASP.NET Web Application template provides a good starting point for developers who are new to ASP.NET and want to see a sample implementation, as well as developers who want to quickly get a site up. Figure 1-3 shows the default page of this application.
The ASP.NET Empty Web Application template takes the opposite approach. It contains no pages or code — only a nearly empty web.config file. This template contains only the references required by an ASP.NET website. It is designed to give experienced developers maximum flexibility when building their website. Figure 1-4 shows the structure of an ASP.NET Empty Web Application project as viewed in Solution Explorer.
Developers who want maximum control over their web applications will prefer the ASP.NET Empty
Web Application template.
The features discussed thus far allow developers to improve on applications without changing the
way they write those applications. However, Microsoft recently released ASP.NET MVC — a set of
tools that provide a new way to build web applications.
FIGURE 1-3: Default application page
FIGURE 1-4: Structure of an ASP.NET Empty Web Application project
JQUERY
Because web forms have been around for a long time, developers can find countless user controls to enhance their web applications. Microsoft and numerous third-party vendors have produced libraries of rich controls to provide extra functionality to ASP.NET websites.
Many of these Web Forms controls rely on page events and code-behind. Therefore, they do not work with the new ASP.NET MVC paradigm. Developers can still enhance their applications by adding rich client-side interactions using JavaScript. Many of the same component vendors who built Web Forms controls are working on and releasing controls designed for MVC. In many cases, they use JavaScript to provide client-side interactivity.
JavaScript is an excellent tool to interact with a web page because of the following reasons:
· It is a standard language that runs within all modern desktop browsers.
· It interacts with the Document Object Model (DOM) exposed by a web page, allowing web developers to manipulate the objects on a page.
· It has a rich event model for building interactive applications. Unfortunately, JavaScript has several disadvantages that have limited its usefulness and popularity, including the following:
· The learning curve for JavaScript can be steep for some developers.
· Each browser has its own implementation of the DOM, forcing developers to write and test the same functionality multiple times to ensure the code runs correctly in a variety of browsers.
Several libraries have been built on top of JavaScript to address these disadvantages. These libraries abstract away the complexity of JavaScript, and (more important) automatically detect and handle the differences interacting with the variety of DOM implementations among the major browsers.
jQuery is an Open Source JavaScript library that has gained a lot of popularity in recent years, thanks to its rich set of functions and ease of use. With Visual Studio 2010, Microsoft made the decision to include jQuery with the product, which has boosted its popularity even more. A new ASP.NET MVC project includes a Scripts folder that contains a dozen .js files. These files contain jQuery functions that the project’s web pages can call. You can replace these files with new versions downloaded from http://jquery.com. Each filename contains a number (such as 1.4.1) just before the file extension. This is the version number of jQuery with which the script file is associated
.
This naming convention makes it easy to tell which version of jQuery a site is running. To use jQuery in a view page, reference either files in the Scripts folder or files hosted on a Content Delivery Network (CDN), such as the one hosted by Microsoft at http://ajax.microsoft.com/ajax/jquery. The jQuery script files (for example, jquery-1.4.4.min.js) are stored in this folder.
Link to each .js file you wish to use on your page.
Each location typically contains two versions of each file: one ending in .js and one ending in .min.js. The .min.js version is a minified version of the script, meaning that comments and excess white space have been removed, and variable and function names have been shortened. I always use the minified versions because they are smaller and, therefore, faster to download to the client.
Add the following line to the top of the page to make jQuery functionality available:
<script src=”[FULL_SCRIPT_PATH]” type=”text/javascript”></script>
In this snippet, [FULL_SCRIPT_PATH] is the path and filename of the script file used by the page.
For example, add the following line to use the main jquery file in the project’s Scripts folder from
within the sample site’s master page (Shared\_Layout.cshtml):
<script src=”@Url.Content(“~/Scripts/jquery-1.4.4.min.js”)”
type=”text/javascript”></script>
The Url.Content method specifies an absolute path, so that the .js file will be found, regardless which view is rendered, and in which folder that view is found. I prefer to reference this script from my site’s master pages.
JQuery code is simply JavaScript. Therefore, all jQuery code belongs within
<script language=”javascript”></script> tags.
A common pattern for jQuery syntax is as follows:
$(Selector).Event(Action);
In this snippet, $ is simply the dollar sign character, which represents the jQuery object; Selector is a jQuery selector function (more on this later); Event is an event fired by the selected objects; and Action is the code to run when the event fires. Each call to a jQuery function begins with the $ symbol. This symbol indicates that the JavaScript that follows is jQuery syntax. You can replace the $ with the keyword jQuery, but $ is far more terse. A jQuery selector uses syntax similar to the selectors in CSS and always returns a collection of elements that match the selector criteria. The selector syntax can take several forms:
· Enclosing a tag name in quotation marks selects all elements of a given tag. For example, (“div”) selects all div elements on a page.
· Preceding a string with # selects an element by its ID. For example, (“#custIdLabel”)
selects an element with the ID custIdLabel. It would select multiple elements with this ID if
you were foolish enough to have multiple elements on your page with the same ID.
· Preceding a string with . selects all elements to which a given class has been applied. For example, (“.bodyText”) selects an element with the class bodyText.
· You can select elements within elements by separating selectors with a space. For example, (“headerDiv a”) selects anchor tags contained within an element named headerDiv.
Sometimes, the action might be to bind a function to an event, so that function’s code runs when the event is fired. The most common way to do this is to bind an anonymous function to the ready event of the document. For example, the following jQuery code displays an alert message when the user selects the text within a Div with an ID of MyDiv:
$(“#MyDiv”).click(function () {
alert(“You clicked me”);
});
jQuery code often starts by binding code to the ready event of the document object. The document object represents a page’s entire DOM, and the ready event fires when all the elements of the DOM are loaded into memory, making it an ideal time to manipulate elements, or wire up any other events.
Manipulating DOM Elements with jQuery
Take a look at the DemoClick.htm page in the sample project. Following are the relevant parts:
<script type=”text/javascript” language=”javascript”>
$(document).ready(function () {
$(“#Img1”).click(function () {
var newHeight = $(this).height() + 20;
$(this).height(newHeight);
});
});
</script>
…
<img id=”Img1” height=”50” src=”../Images/Grin.png” alt=”Click to grow” />
The page contains an image tag with the ID “Img1”. The JavaScript binds an anonymous function to the document.ready event. The document.ready event fires when the browser has loaded into memory all the objects in the page’s DOM. In jQuery, you may shorten $(document).ready(function() to the more terse syntax $(function(), which I will do in later examples.
This anonymous function binds another function to the click event of the Img1 image.
$(“#Img1”).click(function () {
Notice the selector: $(“#Img1”). The # symbol preceding “Img1” tells jQuery to search for any elements with an ID of “Img1”. A selector returns a set of elements matching the selection criteria. In this case the selector finds one such element on the page, so it returns a set containing that one matching element. The code then binds an anonymous function to the click event of the matching element. The code of the anonymous function is as follows:
var newHeight = $(this).height() + 20;
$(this).height(newHeight);
In this code, the variable newHeight is declared and assigned. The code uses the keyword this to identify the element that fired the event. In this case, it is the image element that fired the click event, so $(this) refers to the image element. The code retrieves the height of the image element and increments it by 20 pixels before assigning this sum to the newHeight variable. The result is a page that displays an image. Each time the user clicks the image, it grows 20 pixels larger.
Calling Server Code with jQuery
A powerful use of jQuery is its capability to call RESTful web services on the server. This gives a web application the capability to call server code without posting back an entire page. ASP.NET MVC provides a simple way to expose RESTful services that can be called from jQuery. Recall that each Controller Action method returns an ActionResult object. The MVC framework provides the JsonResult class — a subclass of ActionResult that returns data in the JSON format. JSON is a lightweight, text-based data format designed for transmitting data across the web.
The EmployeeController class in the HR sample application contains a GetAllEmployees action
method that returns a JsonResult object. Following is the code:
public JsonResult GetAllDepartments()
{
var empBus = new DepartmentBusiness();
List<DepartmentDTO> departments = empBus.GetAllDepartments();
return Json(departments, JsonRequestBehavior.AllowGet);
}
This code looks similar to the GetAllDepartments method in the DepartmentController class. The difference is that the last line uses the Json helper method to pass to the view engine a JsonResult object, instead of a ViewResult object. The result is that data is sent to the client as JSON — a data format that is small and self-describing, and, therefore, well-suited for passing data between client and server.
return Json(departments, JsonRequestBehavior.AllowGet);
The Json method here passes the list of departments down to the view engine. The second parameter
of the method enables this service method to be called via HTTP GET. By default, only POST methods are enabled.
This method can be called directly from a jQuery script on a web page without refreshing that page.
The EditJQ.aspx page contains the following script:
$ (function () {
var url = “/Employee/GetAllDepartments”;
$.getJSON(
url,
null,
function (data) {
var options = “”;
for (var i= 0; i< data.length; i++) {
options += “<option value=” + data[i].DepartmentId + “>”
+ data[i].DepartmentName + “</option>”;
}
$(“#DepartmentSelect”).append(options);
});
});
When the document’s ready event fires, the script calls the jQuery getJSON function, which calls the RESTful web service function GetAllDepartments. The last parameter of getJSON is a callback function that runs after the web service returns. The data parameter is the return value from the web service — in this case, a List of departments.
The selector $(“#DepartmentSelect”) selects an empty drop-down list on the page with the ID DepartmentSelect. The function loops through the list of departments and builds up an option tag for each department. It then appends the list of option tags to the empty drop-down list.