Upload
donrajah
View
230
Download
0
Embed Size (px)
Citation preview
8/12/2019 Looking Ahead to ASP
1/64
Looking Ahead to ASP.NET 4.0K. Scott AllenWhen Visual Studio 2010 and .NET 4.0 arrive next year, we ASP.NET developers will have two mature
frameworks for building Web applications: the ASP.NET Web Forms framework and the ASP.NET MVC
framework. Both build on top of the core ASP.NET runtime, and both are getting some new features to start the next
decade.
I dont have the space to cover every addition to ASP.NET in one article, as there are numerous improvements to
both frameworks and the underlying runtime. Instead, Ill highlight what I think are the important new features for
Web Forms and MVC.
New For ASP.NET Web Forms
ASP.NET Web Forms will be over eight years old by the time Microsoft releases Version 4, and the team continues
to refine the framework and make improvements. In my last column, I touched on a few of these improvements, like
the new classes that make it easy to use the URL routing features now included in the core services of ASP.NET,
and the new MetaKeywords and MetaDescription properties on the Page base class that make it simple to control the
content of metatags on a form. These changes are relatively minor, however.
The key changes in Web Forms address some of the chief criticisms about the framework. Many developers have
wanted more control over the HTML a Web form and its controls produce, including the client-side identifiers
emitted inside the HTML. In 4.0, many of ASP.NETs server-side controls were reworked to produce HTML that is
easier to style with CSS and conforms to conventional Web practices. Also, new properties have been added to base
classes that will give developers more control over the client-side identifiers generated by the framework. Ill
highlight these changes in the following sections.
CSS-Friendly HTML
One example of a server control that is notoriously difficult to style with CSS is the ASP.NET menu control. When
the menu renders, it emits nested table tags that include cellpadding, cellspacing and border attributes. To make
matters worse, the menu control embeds style information inside the cells of the nested tables and injects an in-line
style block at the top of the page. As an example, look at the following definition of a simple menu:
In ASP.NET 3.5, the simple menu produces the following HTML (with some attributes omitted or shortened for
clarity):
8/12/2019 Looking Ahead to ASP
2/64
border="0" width="100%">
Home
In ASP.NET 4.0, Microsoft revised the menu control to produce semantic markup. The same menu control in
ASP.NET 4.0 will produce the following HTML:
Home
This type of CSS-friendly markup was achievable in previous versions of ASP.NET if you used a control adapter to
provide alternate rendering logic for a control, but now the markup is CSS-friendly by default. If you already have
style sheets and client script written against the HTML produced by ASP.NET 3.5, you can set the
controlRenderingCompatibilityVersion attribute of the pages section in web.config to the value 3.5, and the
control will produce the nested table markup we saw earlier. The default value for this attribute is 4.0. Note that the4.0 menu control still produces a style block at the top of the page, but you turn this off by setting the
IncludeStyleBlock property of the control to false.
Many other controls in 4.0 are CSS-friendly as well. For example, validation controls like the RangeValidator and
RequiredFieldValidator will no longer render inline styles, and template controls like the FormView, Login, and
Wizard control will no longer render themselves inside of a table tag (but only if you set the RenderOuterTable
property on these controls to false). Other controls have changed, too. As just one example, you can force the
RadioButtonList and CheckBoxList controls to render their inputs inside of list elements by setting the
RepeatLayout property to the value OrderedList or UnorderedList, which forces the controls to render using ol and li
elements, respectively.
Generating Client IDs
If you have ever written client-side script to manipulate the DOM, then you are probably aware of ASP.NETs
affinity for changing client-side ID attributes. In an effort to ensure that all ID attributes are unique on a page,
ASP.NET will generate a client ID by concatenating a controls ID property with additional informa tion. On the
server, you can access the generated value using the ClientID property of a control.
As an example, if a control is inside a naming container (a control that implements the INamingContainer interface,
as user controls and master pages do), then ASP.NET produces the ClientID value by prefixing the naming
containers ID to the controls ID. For data -bound controls that render repeating blocks of HTML, ASP.NET will
add a prefix that includes sequential numbers. If you view the source of any ASP.NET page, youll probably
8/12/2019 Looking Ahead to ASP
3/64
encounter id values like ctl00_content_ctl20_ctl00_loginlink. These generated values add an extra level of
difficulty when writing client script for a Web Forms page.
In Web Forms 4.0, a new ClientIDMode property is on every control. You can use this property to influence the
algorithm ASP.NET will use for generating the controls ClientID value. Setting the value to Static tells ASP.NET
to use the controls ID as its ClientID, with no concatenation or prefixing. For example, the C heckBoxList in the
following code will generate an tag with a client id of checklist, regardless of where the control exists on the
page:
Candy
Flowers
When using a ClientIDMode of Static, youll need to ensure the client identifiers are unique. If dup licated id values
exist on a page, youll effectively break any scripts that are searching for DOM elements by their ID value.
There are three additional values available for the ClientIDMode property. The value Predictable is useful for
controls implementing IDataBoundListControl, like the GridView and ListView. Use the Predictable value in
conjunction with the ClientIDRowSuffix property of these controls to generate client IDs with specific values
suffixed to the end of the ID. For example, the following ListView will bind to a list of Employee objects. Each
object has EmployeeID and IsSalaried properties. The combination of the ClientIDMode and ClientIDRowSuffix
properties tell the CheckBox to generate a client ID like employeeList_IsSalaried_10, where 10 represents the
associated employees ID.
Another possible value for ClientIDMode is Inherit. All controls on a page use a ClientIDMode of Inherit by default.
Inherit means the control will use the same ClientIDMode as its parent. In the previous code sample, the CheckBox
inherits its ClientIDMode value from the ListView, which holds the value Predictable. The final possible value for
ClientIDMode is AutoID. AutoID tells ASP.NET to use the same algorithm for generating the ClientID property as
it does in Version 3.5. The default value for a pages ClientIDMode property is AutoID. Since all controls on a page
default to using a ClientIDMode of Inherit, moving an existing ASP.NET application to 4.0 will not change the
algorithm the runtime uses to generate client ID values until you make a change to a ClientIDMode property. This
property can also be set in the pages section of web.config to provide a different default for all pages in an
application.
New Project Template
8/12/2019 Looking Ahead to ASP
4/64
The Web application and Web site project templates in Visual Studio 2008 provide a Default.aspx page, a
web.config file and an App_Data folder. These starting templates are simple and require some additional work
before you can get started on a real application. The same templates in Visual Studio 2010 provide more of the
infrastructure you need to build an application using contemporary practices. A screen capture of a brand new
application produced by these templates is shown in Figure 1.
Figure 1 New Web Application in Visual Studio 2010
Notice how the new application includes a master page by default (Site.master). All of the .aspx files you find inside
the new project will be content pages using ContentPlaceholder controls to plug content into the structure defined by
the master page. Notice the new project also includes a style sheet in the Content directory (Site.css). The master
page includes this style sheet using a link tag, and inside the style sheet youll find a number of styles defined to
control the appearance of the page body, headings, primary layout and more. The new project also includes a Scripts
directory with the latest version of the jQuery library, an open source JavaScript framework officially supported by
Microsoft and included with Visual Studio 2010 as part of the install.
The new project template, with its use of master pages and style sheets, will help developers get started in the right
direction when using Web Forms. A running version of the new application is shown in Figure 2. Visual Studio
2010 will also include Empty templates for both Web sites and Web applications. These empty templates will not
include files or directories when you use them, so youll be starting your application from scratch.
8/12/2019 Looking Ahead to ASP
5/64
Figure 2 Running the new ASP.NET Application
Another bit of good news about new projects in ASP.NET 4.0 is that the web.config file starts off nearly empty.
Most of the configuration we became accustomed to seeing in ASP.NET 3.5 web.config files is now in the
machine.config file that lives underneath the 4.0 frameworks installation directory. This includes the configuration
of controls from the System.Web.Extensions directory, the HTTP handlers and modules configured to support
JavaScript proxies for Web services, and the system.webserver section for Web sites running under IIS 7.
New for ASP.NET MVC
Visual Studio 2010 should bring us the second release of the ASP.NET MVC framework. While still young, the
framework has attracted many Web developers who wanted a framework designed for testability. The second
release of ASP.NET MVC is going to focus on better developer productivity and adding the infrastructure to handle
large, enterprise-scale projects.
Areas
One approach to building an extremely large ASP.NET Web Forms application is to break apart the application into
multiple sub-projects (an approach promoted by the P&P Web Client Composite Library). This approach is difficult
to undertake with ASP.NET MVC 1.0 because it works against a number of the MVC conventions. MVC 2.0 will
officially support this scenario using the concept of an area. An areaallows you to partition an MVC application
across Web application projects, or across directories inside of a single project. Areas help to separate logically
different pieces of the same application for better maintainability.
The parent area of an MVC Web application is an MVC project that will include a global.asax and root level
web.config file for the application. The parent area can also include common pieces of content, like application-wide
style sheets, JavaScript libraries, and master pages. Child areas are also MVC Web application projects, but since
these projects physically exist underneath the parent area project at runtime, the parent and its children will appear
as a single application.
As an example, imagine a large inventory application. In addition to the parent area, the inventory application might
be broken into ordering, distributing, reporting and administrative areas. Each area can live in a separate MVC web
project, and each project will need to register its routes by including a class that derives from the abstract base class
AreaRegistration. In the code that follows, we override the AreaName property to return the friendly name of the
reporting area, and override the RegisterArea method to define the routes available in the reporting area:
public class ReportingAreaRegistration : AreaRegistration
8/12/2019 Looking Ahead to ASP
6/64
{
public override string AreaName
{
get { return "Reporting"; }
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
// route name
"ReportingDefault",
// url pattern
"reporting/{controller}/{action}",
// route defaults
new { controller = "Home", action = "Index" },
// namespaces
new string[] { "Reporting.Controllers" });
}
}
Notice that we include a string array of namespaces to search when locating the controller for the reporting area.Constraining the namespaces to search allows different areas to have controllers with the same name (multiple
HomeController classes can exist in the application, for example).
DataAnnotations for Easy Validation
The DefaultModelBinder in ASP.NET MVC is responsible for moving data from the request environment into
model properties. For example, when the model binder sees a model object with a property named Title, it will look
through the form, query string and server variables to find a variable with a matching name (Title). However, the
model binder doesnt perform any validation checks beyond simple type conversions. If you want the Title property
of your model object to contain only strings with 50 characters or less, you have to perform this validation check
during the execution of your controller action, implement a custom model binder or implement the IDataErrorInfo
interface on your model.
In ASP.NET MVC 2.0, the DefaultModelBinder will look at DataAnnotation attributes on model objects. TheseDataAnnotation attributes allow you to provide validation constraints on your model. As an example, consider the
following Movie class:
public class Movie
{
[Required(ErrorMessage="The movie must have a title.")]
8/12/2019 Looking Ahead to ASP
7/64
[StringLength(50, ErrorMessage="The movie title is too long.")]
public string Title { get; set; }
}
The attributes on the Title property tell the model binder that the Title is a required field, and the maximum length of
the string is 50 characters. The MVC framework can automatically display the ErrorMessage text in the browserwhen validation fails. Additional built-in validation attributes include an attribute to check a range and an attribute
to match a regular expression.
At the time of this writing, the MVC runtime uses only the validation attributes for server-side validation checks.
The MVC team expects to generate client-side validation logic from the validation attributes by the time it releases
MVC 2.0. Driving both the server- and client-side validation using these attributes will be a boon for the
maintainability of an application.
Templated Helpers
Templated helpers in ASP.NET MVC 2.0 also consume DataAnnotation attributes. But instead of using the
attributes to drive validation logic, template helpers use the attributes to drive the UI display of a model. The
template helpers begin with the new HTML helper methods DisplayFor and EditorFor. These helper methods will
locate the templates for a given model based on the models type. For example, lets use the Movie c lass we looked
at before, but with an additional property:
public class Movie
{
// ...
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
}
In this scenario, every movie carries its release date, but no one ever cares what time of day a movie is released. We
only want to display the date information when displaying this property, and not the time information. Notice the
property is decorated with a DataType attribute that advertises our intention.
To properly display the release date, we need a display template. A display template is just a partial view with an
.ascx extension that lives inside a DisplayTemplates folder. The DisplayTemplates folder itself can live underneath a
controllers view folder (in which case the template applies only to the views for that one controller), or in the
shared views folder (in which case the template is available everywhere). In this case, the template needs the name
Date.ascx and looks like the following:
In order for the MVC framework to use this template, we need to use the DisplayFor helper method when rendering
the ReleaseDate property. The code shown in Figure 3is from another template, the Movie.ascx display template.
Figure 3Movie.ascx Display Template
8/12/2019 Looking Ahead to ASP
8/64
Fields
Title:
m.Title) %>
m.Title) %>
m.ReleaseDate) %>
m.ReleaseDate) %>
Notice how the LabelFor and DisplayFor helper methods are strongly typed, which can help you propagate changes
if a model is refactored. To use the Movie.ascx template to display a movie anywhere in an application, we just need
to use the DisplayFor helper again. The following code is from a view that is strongly typed against the Movie class:
Movie:
m) %>
The DisplayFor method is strongly typed to use the same model as the view page, so the m parameter in the
DisplayFor lambda expression is of type Movie. DisplayFor will automatically use the Movie.ascx template when
displaying the movie (which in turn uses a DisplayFor to find the Date.ascx template). If we did not use the
DataType attribute on the ReleaseDate property of a movie, DisplayFor would not use the Date.ascx template and
would display the date and the time portions of the ReleaseDate, but the DataType attribute helps guide the
framework to the correct template. This concept of strongly typed, nested templates and data type annotations is
powerful and will prove to be a productivity boost.
8/12/2019 Looking Ahead to ASP
9/64
Exploring ASP.NET 4.0Web Forms
and BeyondDino EspositoASP.NET is a stable and mature platform for building rich and powerful Web applications, so it's hard to imagine a
new set of compelling features being added to it. But last fall, with the release of Service Pack 1 for ASP.NET 3.5,
Microsoft refined the platform's built-in AJAX support and enhanced its productivity by shipping Dynamic Data
controls, a new framework of components specifically designed to address the needs of data-driven and data-entry
applications.
In parallel, Microsoft developed a brand-new, alternative programming model called ASP.NET MVC. Unlike the
classic Web Forms model, ASP.NET MVC helps developers create Web applications in accordance with a widely
recognized design pattern: the Model View Controller.
Today, the overall ASP.NET platform is made up of a few distinct components: Web Forms, ASP.NET MVC,
Dynamic Data controls and ASP.NET AJAX. The upcoming ASP.NET 4.0 platform has the same foundation as the
latest 3.5 SP1 version, but it provides further refinement in the areas of Web Forms, Dynamic Data controls and, lastbut not least, ASP.NET AJAX.
In this article, I'll take a look at what's new and improved in the Web Forms model. In future columns, I'll address
the Dynamic Data control platform as a whole and explore in-depth the developments in the ASP.NET AJAX
environment.
ASP.NET Web Forms 4.0 at a Glance
The key words to describe what's new in the overall ASP.NET 4.0 platform are "more control." ASP.NET 4.0 is
neither a revolutionary change nor a refactoring of its existing architecture. It consists, instead, of a good number of
small-scale changes that together provide developers with much more control of certain frequently used features of
the existing framework.
For example, ASP.NET 4.0 Web Forms give developers more control over viewstate management, generation ofIDs in the context of data-bound controls, and HTML generated by some template-based controls. In addition, you'll
find new families of pluggable components for features that weren't supporting the provider 2009 model in earlier
versions of ASP.NET and a finer control over the linking of external script files through the ScriptManager control.
Let's start with viewstate management.
More Control Over the Viewstate
I say nothing new by stating that the viewstate has been one of the most controversial features of ASP.NET since the
advent of the platform. Too many developers are still convinced that the viewstate is a waste of bandwidth and an
unacceptable burden for each and every ASP.NET page. Nearly the same set of developers eagerly welcomed
ASP.NET MVC because of its complete absence of viewstate. Recently, while teaching an ASP.NET MVC class, I
discussed a master/detail scenario in which the user could select a customer from a list to see more details. I
populated the list during the loading of the page, as expected. Next, while handling the selection-changed event, Ishowed how to fill in the customer's details. However, to have the list available for another selection, I also had to
explicitly repopulate it.
Students promptly noted the extra work required to fill in the list at every server action. Couldn't this be
automatically filled as in Web Forms? Well, in ASP.NET Web Forms you don't need to refill data-bound controls
over a postback just because of the viewstate.
http://msdn.microsoft.com/en-us/magazine/cc300817.aspxhttp://msdn.microsoft.com/en-us/magazine/cc300817.aspxhttp://msdn.microsoft.com/en-us/magazine/cc300817.aspx8/12/2019 Looking Ahead to ASP
10/64
In short, the viewstate is not there only to reduce your bandwidth. The viewstate is functional to the Web Forms
model, as it caches some of the content for the controls in the page. Next, the ASP.NET infrastructure takes care of
reading that information from the viewstate to restore the last known good state for each control within the page.
As widely known, but also largely overlooked, the viewstate is an optional feature. The viewstate support is turned
on for each page by default, but developers have a Boolean property available to change the default setting and do
without it. The property is named EnableViewState and is defined on the System.Web.UI.Control class. It should be
noted that the System.Web.UI.Page class inherits from the Control class. As far as the viewstate is concerned, an
individual control and the page are one and the same.
For any ASP.NET page, turning off the viewstate couldn't be easier. You set EnableViewState to false either
declaratively or programmatically during the page's life cycle, as follows:
void Page_Load(object sender, EventArgs e)
{
Figure 1 The ViewStateMode Enumeration
Value Description
Inherit Inherits the value ofViewStateMode propertyfrom the parent control.
Enabled Enables viewstate for thiscontrol even if the parentcontrol has viewstatedisabled.
Disabled Disables view state for thiscontrol even if the parentcontrol has viewstateenabled.
msdn magazine
2
Cutting Edge
// Disable viewstate for the page
// and ALL of its child controls
this.EnableViewState = false;
...
}
The EnableViewState property indicates whether the control is allowed to cache its own UI-related state. Be
reminded that the viewstate setting in ASP.NET has a hierarchical nature, which means that if the viewstate is
enabled on the parent control, it cannot be disabled on any of its child controls. The following code has no effect on
the behavior of the text box if the viewstate is enabled at the page or container level:
protected void Page_Load(object sender, EventArgs e)
{
8/12/2019 Looking Ahead to ASP
11/64
TextBox1.EnableViewState = false;
}
The IsViewStateEnabled property -- a protected property indeed -- reports about the current state of the viewstate for
a control. But what does all of this mean to developers?
If the viewstate is enabled on the page (which is the default setting), you have no means to keep the state ofindividual controls off the storage. To gain some control over it in ASP.NET 3.5, you need to disable the viewstate
at the page level and then re-enable it where needed, but also keep in mind the hierarchical nature of it. Any
container control that has the viewstate enabled will inevitably push its setting down to the list of its children. This
fact leads to somewhat of a paradox: it is possible for the same control to have the property IsViewStateEnabled set
to true and the property
EnableViewState set to false!
The viewstate is a fundamental piece of the ASP.NET Web Forms architecture, and dropping it entirely from the
platform in the name of a performance gain is arguably not the best option. Years of experience has proved that a
more sustainable option is having the viewstate disabled by default on the page. Even better than that is the change
coming up with ASP.NET 4.0: enabling viewstate control over individual controls.
In ASP.NET 4.0, the System.Web.UI.Control class exposes a new property named ViewStateMode:
public virtual ViewStateMode ViewStateMode { get; set; }
The property takes its feasible values from the ViewStateMode enumerated type, shown in Figure 1.
To preserve compatibility, the default value of the property is Inherit. However, this property gives developers the
possibility of controlling the viewstate setting for individual controls, regardless of the viewstate option of any
parent page or containers.
Only a few of the controls in ASP.NET pages really need viewstate. For example, all text boxes you use to simply
gather text don't need viewstate at all. If Text is the only property you use on the control, then the value of the Text
property would be preserved by cross-page postbacks because of posted values. Any value stored in the viewstate, in
fact, will be regularly overwritten by the posted value. In this case, the viewstate is really unnecessary. But there's
more to notice. Any side properties that are set to a given non-default value on creation, but remain unchanged
during postbacks (such as ReadOnly, BackColor and so on), have no need to go to the viewstate. For example, aButton control that retains the same caption all the time doesn't need the viewstate at all. Up until ASP.NET 4.0,
turning off the viewstate for individual controls was problematic. Things change in the next version. This is the key
takeaway of the ViewStateMode property.
More Control Over Auto-Generated IDs
In ASP.NET pages, using the same ID for two server controls isn't allowed. If this happens, the page won't compile -
- period. In HTML, though, it is possible for two or more elements to share the same ID. In this case, when you
make a search for an element via document.getElementById, you'll simply get an array of DOM elements. What
about nested ASP.NET controls?
Most data-bound, template-based controls generate their output by repeating an HTML template for every data-
bound item. This means that any child control defined with a unique ID in the template is being repeated multiple
times. The original ID can't just be unique. For this reason, since the beginning, the ASP.NET team defined an
algorithm to ensure that every HTML element emitted by an ASP.NET control could be given a unique ID. The ID
resulted from the concatenation of the control ID with the ID of the naming container. Furthermore, in case of
repeated controls (i.e., templates), a numeric index was added for disambiguation. For years, nobody really cared
about the readability of the auto-generated ID, and strings like the following became fairly common:
ctl00$ContentPlaceHolder1$GridView11$TextBox1
8/12/2019 Looking Ahead to ASP
12/64
Looking at this, the first issue that may come to mind is the potential length of the string, which, repeated for several
elements, makes the download larger. More important, such an approach is problematic from a client script
perspective. Predicting the ID of a given control you want to script from the client is difficult, and leads straight to
hard-to-read code. In the first place, you need to know the detailed name being generated for a given HTML element
that is buried in the folds of a grid or any other naming container controls. Second, this name is subject to change as
you rename one of the server controls along the hierarchy. A frequently used trick is the following:
var btn = document.getElementById("");
The trick consists in using ASP.NET code blocks to insert in the HTML source code being generated for the real
client ID of a given control. When master pages or template-based controls are used, the trick is a real lifesaver,
because in this case, the naming container of a plain control ends up being quite a complex hierarchy of controls that
developers often leave unnamed. The actual name of the control, therefore, is subject to a few auto-generated IDs.
In addition to using code blocks, ASP.NET 4.0 supports another option: more control over the algorithm that
generates the client ID of a server control.
The System.Web.UI.Control class now features a brand new property named ClientIDMode. The property can
assume a few predefined values as detailed in Figure 2.
Admittedly, the ID-generation algorithm, especially when master pages are involved, is not easy to understand. It is
guaranteed to generate unique IDs, but ends up with strings that are really hard to predict. A more predictable option
has been introduced primarily to be used with data-bound controls so that developers can easily guess the ID of, say,
a Label control used to render a given property on the nth data item. In this case, you want the ID to reflect the
hierarchy of the control (simplifying the naming container structure to the parent controls) but also a particular key
value, such as the primary key. Consider the following code:
...
In this case, each row of the grid is identified by one or more columns in the data source with a trailing index. Here's
an example:
Panel1_GridView1_ALFKI_1
The GridView is the sole control to support multiple columns. If you have multiple columns to concatenate, then
you use the comma to separate names. The ListView will accept only one column, whereas the Repeater control will
limit to trail a 0-based index and accept no column name.
Finally, note that the ClientIDMode property affects only the ID attribute of the resulting HTML element. By
design, the name attribute remains unchanged.
View Controls Refinements
Most data-bound controls offer the ability to select a given displayed element -- mostly a row. In previous versions
of ASP.NET, the selection was stored as the index of the selected item within the page. This means that for pageable
controls (such as the GridView control), the same selection made on, say, page one is retained on page two unless
you programmatically reset the selection during the page/changing event.
8/12/2019 Looking Ahead to ASP
13/64
In ASP.NET 4.0, the current selection on a data-bound control is tracked via the value on the data key field you
indicate through the DataKeyNames property. To enable this feature, you use the new PersistSelection Boolean
property and set it to true. The default value is false for compatibility reasons.
In addition, the FormView and ListView controls offer a little better control over their generated HTML markup. In
particular, the FormView now accounts for a brand new RenderTable Boolean property. If you set it to false (the
default is true), then no extra HTML table tags will be emitted and the overall markup will be easier to style via
CSS. The ListView no longer needs a layout template in ASP.NET 4.0:
The preceding code snippet is sufficient to repeat the content of the CompanyName column for each element in thedata source.
HTML Enhancements
In the beginning, ASP.NET didn't offer much programmatic control over all possible tags of a Web page. For a long
time, the title of a page missed an ad hoc property on the Page class. The same could be said for other popular
features, like CSS files.
In ASP.NET 4.0, the Page class exposes two new string properties to let you set some common tags in the
section of a page. The two new properties are Keywords and Description. The content of these server properties will
replace any content you may have indicated for the metatags as HTML literals.
The Keywords and Description properties can also be set directly as attributes of the @Page directive, as in the
following example:
In ASP.NET, when you invoke Response.Redirect, you return the browser an HTTP 302 code, which means that the
requested content is now available from another (specified) location. Based on that, the browser makes a secondrequest to the specified address, and that's it. A search engine that visits your page, however, takes the HTTP 302
code literally. This is the actual meaning of the HTTP 302 status code in that the requested page has been
temporarily moved to a new address. As a result, search engines don't update their internal tables and when the user
clicks to see your page, the engine returns the original address. Next, the browser gets an HTTP 302 code and makes
a second request to finally display the desired page.
8/12/2019 Looking Ahead to ASP
14/64
To smooth the whole process, in ASP.NET 4.0 you can leverage a brand new redirect method, called
RedirectPermanent. You use the method in the same way you use the classic Response.Redirect, except that this
time, the caller receives an HTTP 301 status code. Code 301 actually means that the requested content has been
permanently moved. For the browser, it makes no big difference, but it is a key difference for search engines.
Search engines know how to process an HTTP 301 code and use that information to update the page URL reference.
Next time they display search results that involve the page, the linked URL is the new one. In this way, users can get
to the page quickly and save themselves a second round-trip.
More Control over Output Caching
In ASP.NET 2.0, several key parts of the ASP.NET runtime were refactored and made much more flexible and
configurable. This was achieved through the introduction of the provider model. The functionality of some
ASP.NET core services, including session state, membership and role management, were abstracted to a sort ofservice contract so that different implementations of a given service could be used interchangeably and
administrators could indicate the one they wanted from the configuration file.
For example, under the hood of the old faithful Session object, there's an instance of the HttpSessionState class
whose content is retrieved by the selected session state provider. The default session state provider gets data from
the in-process memory (specifically, from a slot within the Cache dictionary), but additional providers exist to store
data in databases and external host processes.
8/12/2019 Looking Ahead to ASP
15/64
In ASP.NET 4.0, the provider model covers another extremely important feature of ASP.NET that for some reason
was left behind in previous versions: the output caching.
There are many situations where it is acceptable for a page response to be a little stale if this brings significant
performance advantages. Think of an e-commerce application and its set of pages for a products catalog, for
example. These pages are relatively expensive to create because they could require one or more database calls and
likely some form of data join. Product pages tend to remain the same for weeks and are rarely updated more than
once per day. Why should you regenerate the same page a hundred times per second? Since ASP.NET 1.0, output
caching allows you to cache page responses so that following requests can be satisfied returning the cached output
instead of executing the page. Figure 3shows the sequence of application events, including the step where the
system attempts to resolve the request looking into the output cache.
Figure 5 Split Script Files in the Microsoft AJAX Library for ASP.NET 4.0
File Goal
MicrosoftAjaxCore.js Core functionalities of the library
MicrosoftComponentModel.js Base classes for the client-side objectmodel
MicrosoftAjaxSerialization.js JSON serialization
MicrosoftAjaxGlobalization.js Data and funtions for globalization
MicrosoftAjaxHistory.js History points and the client API forhistory management
MicrosoftAjaxNetwork.js Raw AJAX and HTTP functionalities
MicrosoftAjaxWebServices.js Wrapper client API for invokingservices
MicrosoftAjaxApplicationServices.js Wrapper client API for predefinedASP.NET services such as
authenticationMicrosoftAjaxTemplates.js Client-side rendering API for ASP.NETAJAX 4.0
MicrosoftAjaxAdoNet.js Wrapper client API for ADO.NETservices in ASP.NET AJAX 4.0
8/12/2019 Looking Ahead to ASP
16/64
Up until now, any page output (which can be grouped by form and query string parameters, requesting URL, or
custom strings) is stored in memory in a private area of the ASP.NET Cache. In the long run, the amount of the
output cache puts additional pressure on the Web server machine by consuming memory and generating frequent
updates on the Cache object. In ASP.NET 4.0, the output caching subsystem fully supports the provider model, thus
giving developers the opportunity of storing page responses outside the ASP.NET worker process.A custom output
cache provider is a class that derives from OutputCacheProvider. The name of the class must be registered in the
configuration file, as shown below:
As usual, you can have multiple providers registered and select the default one via the defaultProvider attribute on
the outputCache node. The default behavior is offered through the AspNetInternalProvider object that turns out to be
the default provider, if you don't change anything in the configuration file.
Figure 7 The MicrosoftAjaxMode Enumeration
Value Description
Enabled Legacy option, indicates that justone file will be linked from thepages as in previous versions ofASP.NET.
8/12/2019 Looking Ahead to ASP
17/64
Disabled No script file is automaticallyreferenced from theScriptManager control.
Explicit Script files to be referenced areexplicitly listed in the Scripts
section of the ScriptManagercontrol.The output cache provider doesn't have to be the same for all pages. You can choose a different provider on a per-
request basis or even for a particular user control, page, or combination of parameters for a page. You can specify
the provider name in the @OutputCache directive wherever this directive (page and/or user controls) is accepted:
To change the provider on a per-request basis, instead, you need to override a new method in global.asax, as shown
below:
{
// Decide which provider to use looking at the request
string providerName = ...;
return providerName;
}
Starting with version 2.0, session state can be stored outside the memory of the worker process. This means that any
data stored in the Session object must be serialized to and from an out-of-process environment. If you look back
at Figure 3, session state is loaded into the Session object around the AcquireRequestState application event. The
in-memory content is then serialized back to storage at the end of the request processing.ASP.NET 4.0 enables developers to request some compression to be applied to the data stream being sent in and out
of the session provider (see Figure 4). Compression is obtained by using the GZipStream class instead of a plain
Stream class to do any serialization:
To enable compression, you simply add the compressionEnabled attribute to the sessionState section of the
configuration file. By default, compression is not enabled.
Any JavaScript library is made up of myriad specific JavaScript files with a more or less sophisticated graph of
interconnections. ASP.NET AJAX, instead, always tried to abstract JavaScript details away from developers and
offered a rather monolithic client JavaScript library, via the ScriptManager control. This will change in ASP.NET
4.0. The Microsoft AJAX client library has been refactored and split into the individual files listed in Figure5. Figure 6 shows the dependencies between individual script files in the overall library.
A new property has been added to the ScriptManager control that lets you specify how the building blocks of the
library should be handled. The property is MicrosoftAjaxMode, and it accepts values as shown in Figure 7.
Better Platform
ASP.NET 4.0 Web Forms contains a number of small-scale changes that, taken together, make it a better
development platform. Web Forms is a mature framework that needs refinement, not redesign. If you don't feel
8/12/2019 Looking Ahead to ASP
18/64
entirely comfortable with Web Forms and are looking for something completely different, then ASP.NET MVC is
worth a careful look.
Data Binding in ASP.NET AJAX 4.0Stop beating around the bush: AJAX is possible only with a strong JavaScript engine that runs within the client
browser and provides the foundation for more advanced and asynchronous features. The JavaScript library currently
incorporated in ASP.NET 3.5 Service Pack 1 is a necessary, but insufficient, attempt to deliver such a library. A
more powerful ASP.NET AJAX platform is required, and it is just being introduced as part of ASP.NET AJAX 4.0.
Abstractly speaking, an AJAX-based front-end is a presentation layer that combines rich UI capabilities with the
implementation of some application logic. The application logic is essentially the code behind all the use-case
diagrams that resulted from the design and analysis phases. The application logic expresses the intended behavior of
the application and how a user is expected to interact with the whole system.
What makes an AJAX front-end fairly unique, at least when compared to a classic Web or smart-client front-end, is
the pressing need to mix elements of a rich user experience with low-level programming tools. Because an AJAX
front-end runs within the client browser, it can rely only on HTML to produce the user interface and only on
JavaScript to spice up the visual elements with special effects, drag-and-drop, asynchronous data fetch and partial
updates.
To meet expectations, a modern and effective AJAX platform must provide two key capabilities. First, it must
enable developers to place asynchronous calls to a HTTP faade of ad hoc server modules. Second, it must enable
developers to incorporate any received raw data into the existing page Document Object Model (DOM). Both
capabilities, though, would lose much of their inherent appeal if implemented in a way that isn't that easy and
effective.
In ASP.NET 3.5 Service Pack 1, developers find a powerful and reliable API to connect asynchronously to a layerof HTTP-based Web services. ASP.NET AJAX 3.5 makes it possible, and easy overall, for you to reference a Web
service from the client page. When you do so, the framework also automatically generates a JavaScript proxy class
that mirrors the service contract. The existing AJAX framework, both on the server and client, works to shield
developers from all details of data serialization. From the perspective of the JavaScript developer, a remote Web
service (still subject to the well-known same-origin policy) is like a local JavaScript object exposing behavior
through methods.
ASP.NET 3.5 Service Pack 1 doesn't offer the same virtues as far as the building of the user interface is concerned.
It makes it very easy to fetch raw data from the server, but it doesn't offer much in the way of a powerful interface to
display this raw data in a user interface. The major weakness of the AJAX support in ASP.NET 3.5 Service Pack 1
is the lack of effective tools for client-side data binding and HTML templates. That is why an engine for client-side
template rendering and a made-to-measure data binding syntax are the most compelling features you find in
ASP.NET AJAX 4.0.
In this article, I'll review the pillars of real-world AJAX development as supported in ASP.NET AJAX 4.0. In doing
so, I'll mostly focus on client-side templates and data binding but won't ignore other goodies, such as ADO.NET
Data Services proxy classes and programming facilities.
Pillars of Real-World AJAX Development
Real-world AJAX development is about building rich user interfaces over the Web, and it requires the application of
new design patterns and employment of new programming tools.
8/12/2019 Looking Ahead to ASP
19/64
For a long time, any Web user interface represented a whole step backward in terms of usability and responsiveness
if compared to any desktop user interface. For a long time, Web developers just ignored (because it was not relevant
to their work) a number of UI patterns and programming features, including predictive fetch, caching, monitoring of
remote tasks, context-sensitive and drill-down display, subviews, partial UI disablement, and modality.
In classic Web development, the building of the user interface was entirely delegated to the server side and
effectively implemented using server-side data binding and ad hoc controls. The advent of the AJAX paradigm
made this mode obsolete and unappealing for increasing numbers of applications.
Data binding, though, is too powerful a feature to overlook in an AJAX programming model. Also, object-
orientation is hard to refuse when the complexity of code grows beyond a given threshold. At the same time, a Web
application remains a pretty unique combination of small footprints, cacheable downloads and rich capabilities.
On the way to real-world AJAX development, JavaScript libraries are the only affordable way to add programming
power. Through JavaScript libraries, you provide the foundation of object-orientation in a non-OOP language; you
offer rich and off-the-shelf UI widgets; and you can offer programming tools to effectively code data binding
entirely on the client-side.
Without a powerful model for client-side data binding, you can't have a powerful platform for real-world AJAX
development.
Requirements for Client-Side Data Binding
There are two fundamental patterns for implementing data binding functionalities. One is the HTML Message
pattern, and the other is the Browser-side Template pattern. The former entails making a remote service call to a
component that returns prearranged HTML markup ready for display. The latter is all about setting up machinery to
download raw data and decide on the client how to render it out.
The HTML Message pattern is similar to a smart form of partial rendering, except that it doesn't involve any view
state and can be configured to be an autonomous operation not bound to any other postback operations occurring in
the same application. In an implementation of the HTML Message pattern, everything takes place on the server; any
data binding is essentially a form of classic server-side data binding involving controls such as DataGrid and
ListView and managed containers of fetched data.
The HTML Message pattern can be easily implemented with the tools available in ASP.NET 3.5. All that it requireson the client is the binding of returned markup to the page DOM. The code snippet below shows what's really
required from a coding perspective:
grid.innerHTML = markup;
In the example, grid indicates the HTML element to contain the markuptypically this is a DIV tag. The variable
named markup, on the other hand, indicates any chunk of HTML obtained as a response from a service method call.
It goes without saying that the service used to implement the HTML Message pattern must incorporate both the
logic to retrieve or calculate the data to return, plus any logic required to format the data to HTML.
In general, a solution based on the HTML Message pattern requires more bandwidth as the average size of the
response for each remote method call increases.
The Browser-side Template pattern (BST) requires more coding on your side but can also deliver better results both
in terms of flexibility and bandwidth optimization. The BST pattern is based on the idea that you place a remote call
to retrieve data. Data is then downloaded on the client in a format that allows manipulation with JavaScript. Finally,
data is merged with the existing page DOM and produces any complex interface you need.
Too often, the power of the AJAX paradigm is mistakenly represented with the possibility of asynchronously
updating small portions of the user interface. It is one thing to get a scalar value asynchronously (say, the current
8/12/2019 Looking Ahead to ASP
20/64
balance of a bank account) and insert that into the existing page DOM; it is quite another thing to refresh
asynchronously an array of data that changes frequently and requires a gridlike infrastructure to display.
The server side is simple with server controls, as below:
Collection stocks = GetLatestQuotes(...);
DataGrid1.DataSource = stocks;
DataGrid1.DataBind();
What would be the equivalent of such code for the client side? The first part can be easily mapped to the features of
ASP.NET 3.5. All you do is instantiate and use a client proxy for a remote service that is capable of getting you up-
to-date values, like so:
var service = new Samples.Services.FinanceService();
var stocks = service.GetLatestQuotes(...);
The stocks variable is a JavaScript array of objects that represents the data you received. How would you fit this
chunk of raw data into an existing HTML layout? The BST pattern is here to help. It requires that you define the
following elements: your own syntax for HTML templates and related data placeholders; your own syntax forbinding actual data to placeholders; an HTML factory that takes templates and data and produces updated markup;
and glue code to tie it up all together while offering a manageable programming interface.
ASP.NET AJAX 4.0 provides an implementation of the BST pattern out of the box. The scaffolding for ASP.NET
AJAX templates is defined in the MicrosoftAjaxTemplates.js file. You need to reference this file via the
ScriptManager control (or ScriptManagerProxy if you use master pages). If you use ASP.NET MVC or prefer to
reference script files via the traditional tag, then you must also add a preliminary reference to
MicrosoftAjax.js.
Syntax for HTML Templates
Years of ASP.NET programming have proven beyond any reasonable doubt that HTML templates are an excellent
way to create a Web user interface from data. An HTML template is a piece of HTML that contains literals,ASP.NET controls and placeholders for binding data. Bound to raw data and processed by an ad hoc engine, an
HTML template morphs into plain HTML for the browser to render. A template exists to bind data and originate a
chunk of markup to display; until binding occurs, the template is hidden from view.
In spite of a relatively simple description, an HTML template is quite difficult to implement in a real-world AJAX
framework. A few attempts have been made by popular libraries, such as Prototype JS, to formalize an HTML
template. While there's common agreement on the features one should expect from an HTML template, a common
model for defining an HTML template in a browser doesn't exist yet.
A template must be able to render XHTML-compliant markup. A template must be processed as quickly as possible
by the underlying rendering engine and should let the engine render a large percentage of the markup before the user
realizes there's a delayed response from the application. A template must support a very simple syntax for binding
that is easy to read, while not being limited to simple cases only. You should be able to mix markup and code in a
template. Ideally, the code that triggers the rendering of the template should be declarative and not particularly
intrusive.
Let's review the characteristics of the HTML template model supported by ASP.NET AJAX 4.0.
In ASP.NET AJAX 4.0, an HTML template is a DIV tag, or any other container tag, decorated with the sys-template
class attribute, as shown below:
8/12/2019 Looking Ahead to ASP
21/64
{{ Symbol }}, {{ Quote }}, {{ Change }}
The sys-template CSS class is a convention that marks the element, and its content, as initially invisible. Note that
the sys-template must be defined explicitly in the master page, or in every page, as follows:
.sys-template { display:none; visibility:hidden; }
When rendered, a template is given a data context and the body of the template can host bindings to public fields
and properties of the data context object. Likewise, any elements in the template can reference any JavaScriptexpression that evaluates to a string.
Syntax for Data Bindings
The syntax to express a binding between a placeholder in the template and external data is as follows:
{{ expression }}
As mentioned, the expression can be the name of a public member of the data context object or a JavaScript
expression that returns a string. Such expressions can appear anywhere in the template and can also be used to
assign a value to an attribute, as shown below:
An HTML template doesn't have to be made of plain HTML literals; you can use ASP.NET markup as well. Giventhe preceding code snippet, here's the markup emitted by the Label control:
{{ CompanyName }}
As you can see, the use of a server control in the source code of the page doesn't hinder client-side rendering of
templates.
Client events can be defined within a template using the familiar onXXX syntax or via the $addHandler function in
the Microsoft AJAX Library.
8/12/2019 Looking Ahead to ASP
22/64
DataView Control and Template Instantiation
To display data, a template must be instantiated, bound to data and rendered within a container. The
Sys.UI.DataView client control can be used to automate and simplify all these tasks.
The DataView control is essentially a component that takes some input data and the ASP.NET AJAX template and
produces HTML markup to be displayed within the page. The DataView is also referenced as a behavior component.
In general, a behavior is a script-based component that, once attached to a DOM element, changes the way in whichthe HTML element works within the client browser. You can work with a behavior in either of two ways. You can
declaratively attach the behavior to its target DOM element, or you can create an instance of the behavior and
configure it programmatically. In the latter case, the association between the behavior and the template is just part of
the configuration. Let's tackle the declarative approach first.
Before I go any further, though, let me clarify that the DataView is just one possible behavior component. Anything
you read later on regarding declarative instantiation and attachment applies to any behavior you may run across in
ASP.NET AJAX.
Figure 1The DataView Behavior in Action
Attaching Behaviors DeclarativelyTo attach behaviors to a DOM element, you use the sys:attach custom attribute. As you can see, the attribute is
associated with a namespace URI that makes it XHTML compliant. You declare the sys prefix in the
element:
The sys prefix maps to the javascript:Sys namespace URI defined in the Microsoft AJAX library. Using the
sys:attach attribute serves only the purpose of establishing an association between an existing behavior and an
8/12/2019 Looking Ahead to ASP
23/64
HTML element. You still need to instantiate the behavior component. You do that by defining another custom
namespaced attribute in the element. The value of the attribute will reference the JavaScript object to
instantiate:
The name of the attributedataview, in the preceding code snippetis arbitrary and can be changed to anything
else you like. Whatever name you pick, however, it must be maintained in the remainder of the code to reference the
behavior.
The effective instantiation of any attached script behavior occurs when the page is loaded and the DOM element
gets processed. The browser that is loading the page may not know anything about how to handle such library-
defined behaviors. The ASP.NET AJAX framework is ultimately responsible for the instantiation of its own
behaviors. However, the ASP.NET AJAX framework requires ad hoc instructions from you to proceed. In
particular, you want the framework to kick in during the DOM parsing process and have it look in the content of any
parsed element to take care of any sys:attach attributes.
Figure 2Controlling a DataView Object Programmatically
// Define a global instance of the DataView
var theDataView = null;
// This function can be called from anywhere in the page to
// fill the template with passed data and update the page.
function renderTemplate(dataSource)
{
// Ensure we have just one copy of the DataView.
// The DataView's constructor gets a DOM reference to the template.
if (theDataView === null)
theDataView = new Sys.UI.DataView($get("MyTemplate"));
// Bind data to the template associated with the DataView
theDataView.set_data(dataSource);
// Force the template to render
theDataView.refresh();
}
8/12/2019 Looking Ahead to ASP
24/64
For performance reasons, the ASP.NET AJAX framework is not designed to automatically take care of any DOM
element the browser encounters along the way. It is therefore up to you to explicitly indicate which DOM elements
need to be scanned for attached behaviors that support declarative instantiation. You enable a DOM element to
contain declaratively instantiated behaviors by using the sys:activate attribute. You use the attribute in the
element and set it to a comma-separated list of element IDs:
The preceding code instructs the framework to automatically instantiate any behavior that may be attached to the
customerList DOM element.
You can also use the wildcard symbol (*) if you want to activate the whole document. Use this option with care,
especially on large pages because it may introduce a rendering delay. With the DataView behavior fully configured
in the element, all that remains to do is to bind fresh data to the template:
{{ ID }}
The DataView component has a rich programming interface that, among other things, includes a data property. The
data property represents the data context for the bound template. You can set the data property both declaratively
and programmatically. In the code snippet below, the data property is declaratively set to the content of a global
array named theCustomers:
...
In general, you can set the data property to any JavaScript expression that evaluates to a bindable object or an array
of objects. You opt for a declarative approach when you intend to bind the template to some global data.
8/12/2019 Looking Ahead to ASP
25/64
The code download sample titled A Sample Page Using Declarative Binding shows the full listing of a sample
page.Figure 1shows the sample page in action.For programmatic binding, you need to obtain a reference to the DataView object and call the setter method of the
data property. You retrieve the DataView instance via the $find helper defined in the Microsoft AJAX library. The
ID of the DataView component matches the ID of the DOM element it is attached to. Consider the following code
snippet:
...
You can perform the data binding only when the user explicitly clicks the button. Here's the code you need to put in
the bind JavaScript function:
function bind() {
theDataView = $find("DataView1");
theDataView.set_data(theCustomers);
}
You first retrieve the DataView instance by ID and then assign new content to its data property.
Tips for Master Pages
When you use a master page, you usually leave the tag of the page template in the master. It is then
necessary that you edit the master page to attach any required behavior. Alternatively, you can put the tag in
a content placeholder and force developers to set it explicitly in any content page.
The tag is required to register attachable behaviors, such as DataView, and to enable DOM elements to
recognize and instantiate behaviors through the sys:activate attribute.
It should be noted that an alternative exists to editing the tag. You can use the new
ClientElementsToActivate property on the ScriptManager control, as follows:
8/12/2019 Looking Ahead to ASP
26/64
...
Note that only a few of the properties defined on the ScriptManager control are mirrored on the
ScriptManagerProxy control, which is the wrapper control you use to replicate ScriptManager functionality in acontent page. In ASP.NET 4.0, however, the ClientElementsToActivate is among the few properties you can access
on both controls.
You might be wondering how a string array property like ClientElementsToActivate can affect the behavior of a
JavaScript framework, such as the ASP.NET AJAX framework. When the ClientElementsToActivate property is
set, the script manager control emits an extra line of script within the page that adds one or more entries to an
internal array on the Sys.Application object in the Microsoft AJAX Library.
Using the DataView Control Programmatically
So far, we've examined a scenario in which the HTML template is attached to a DataView behavior for mixing
together layout and data into fresh HTML. This is not the only possible approach to client-side data binding.
You can also create an instance of the DataView component programmatically and pass the template to it to use as
an argument.Figure 2provides a brief but illustrative listing.The constructor of the DataView takes a DOM reference to the template to use internally. The setter method of thedata property gets fresh data to bind. Finally, the refresh method forces an update of the HTML template that
displays freshly bound data.
To create an instance of the DataView, you can also resort to the $create helper method, as shown below:
function pageLoad() {
$create(
Sys.UI.DataView,
{},
{},
{},
$get("MyTemplate")
);
}
A very common scenario in which using a DataView definitely smoothes your programming efforts is to populate a
complex HTML template with data provided by a remote Web service. Let's investigate this point further.
Fetching Data from Web Services
The programming interface of the DataView component features a number of members specifically designed to
serve the scenario in which the content of the DataView comes from a remote URI. The download includes a list of
members of the DataView that work with Web Services.
8/12/2019 Looking Ahead to ASP
27/64
Note that the content of the code download sample titled An Auto-Fetch DataView to Consume Data from a Remote
URI doesn't fully comprehend the entire API of the DataView component. Many more members exist to serve other
scenarios that I'll cover in depth in a future column.
The code download sample titled An Auto-Fetch DataView to Consume Data from a Remote URI shows the
JavaScript code that creates a DataView when the page loads. The DataView is configured to fetch its data
immediately by placing a call to the specified Web service method.
The dataProvider property indicates the data source, whereas the fetchOperation sets the method to invoke. Finally,
fetchParameters is an dictionary object that contains parameter information for the method. You set it to a JavaScript
object where each property matches the name of a formal parameter on the method definition. In particular, in the
previous example, the method GetQuotesFromConfig has the following prototype:
[OperationContract(Name="GetQuotesFromConfig")]
StockInfo[] GetQuotes(bool isOffline);
The DataView receives the HTML template to populate via the $create helper function and once data has been
successfully fetched, it fills up any placeholders in the template.
Figure 3A Rich Data-Bound Web Page Using AJAX and jQueryThe sample code also contains a custom timer object that periodically refreshes the template with a bit of jQuery
animation. When the timer ticks, a new fetch operation is ordered using any current value for the "offline" checkbox.
The "offline" checkbox indicates whether the Web service is expected to return fake stocks and values or connect to
8/12/2019 Looking Ahead to ASP
28/64
a real-world finance service to grab quotes for true stocks. The service gets the URL of the finance service and the
list of stocks from the configuration file. (See the source code for details.)
Next Month
Figure 3 shows a rich and animated data-bound ASP.NET AJAX page that uses client-side rendering to bind raw
data to a relatively complex HTML template. In ASP.NET AJAX 4.0, you find powerful programming tools to
make coding such pages no more difficult than doing traditional server-side data binding.
The page shown in Figure 3 is only the first, and the simplest, step of a longer path. Next month, I'll discuss more
features of rich templates and how to put logic in HTML templates, and I'll explore live data binding. Stay
tuned!
Live Data Binding in ASP.NET AJAX 4.0Dino EspositoRecently I moved into a new office and went through the extremely pleasant and gratifying experience of packing
up all the programming books I had collected in more than 10 years.
Those books could tell you quite clearly how Web programming evolved in the past decade, and which technologies
followed one another, each improving (and in many cases revolutionizing) the other.
One book in particular caught my attention. It covered cutting-edge (well, for that era) programming techniques for
Internet Explorer 4. I couldnt resist the temptation to flip through its pages.
In the late 1990s, most big names in the computer industry were engaged in their first attempts to make the Web and
the browser a dynamic and highly programmable environment.
Data binding was just one of many popular features being researched and developed. While the basic idea of data
binding hasnt changed significantly over the years, a real transformation did occur as far as its application to the
Web world. The common approach to implementing data binding over the Web is radically different today than in
the late 1990s, and much of the difference is due to Asynchronous JavaScript and XML (AJAX).
In this column Ill discuss various forms of client-side data binding as they are coming out in ASP.NET AJAX 4.0.
In particular, Ill focus on some advanced features of data binding and observable objects.
Basic Principles
Generally speaking, data binding is simply a programs ability to bind some members of a target component to the
members of a data source. Rapid Application Development (RAD) tools such as Microsoft Access and Microsoft
Visual Basic made data binding a successful reality.
RAD tools offered an easy and effective infrastructure for developers to bind visual elements to the members of a
data source. For a long time, the data source was uniquely identified with a record-set data stream originating from a
SQL query.
In this regard, data binding nicely fits in a smart-client scenario but poses additional issues if employed in a Web-
client scenario. For example, how would you flow records from the origin database server down to the requesting
JavaScript-equipped browser?
Among many other things, that old book I opened up after years of oblivion discussed the data binding features of
IE4 based on a couple of special ActiveX components, aptly named the Tabular Data Control (TDC) and Remote
Data Services (RDS) control. Figure 1illustrates the overall architecture of client-side data binding as it was
envisioned by IE4 architects in the beginning of the dynamic Web era.
http://msdn.microsoft.com/magazine/ee532098.aspx?sdmr=DinoEsposito&sdmi=authorshttp://msdn.microsoft.com/magazine/ee532098.aspx?sdmr=DinoEsposito&sdmi=authorshttp://msdn.microsoft.com/magazine/ee532098.aspx?sdmr=DinoEsposito&sdmi=authors8/12/2019 Looking Ahead to ASP
29/64
Figure 1Client-Side Data Binding in Internet Explorer 4
A made-to-measure ActiveX control manages the connection with a remote data source and takes care of
downloading (and optionally caching) data. The data source is any ODBC-compliant data source with RDS; its a
server-side text file with TDC.
The actual binding between source and target elements is implemented through browser-specific HTML attributes
such as datasrc, datafld and dataformatas. Heres a quick example:
The content of the bound fieldCompanyName in the exampletakes up the space reserved for the SPAN tag in
the resulting Document Object Model (DOM).
What does the actual job of inserting data into the DOM? As mentioned, its the browser that in this case does the
trick. When the browser encounters any dataXXX attributes, it queries the data source control for data using an
internal, contracted API. Any data it gets is then inserted into the final DOM and displayed to the user.
As you can see, the solution is strongly browser-specific and understandably never captured the heart of developers.
Client-side data binding was then set aside for a few years as ASP.NET and its server-side programming model
gained wide acceptance.
In recent years, the advent of AJAX generated a lot of interest around client-side data binding, and engineers were
back at work finding an effective (and this time cross-browser) way to make it happen.
Evolution in ASP.NET AJAXFigure 2shows the overall architecture of client-side data binding as its implemented in ASP.NET AJAX 4.0.
Figure 2 Client-Side Data Binding in ASP.NET AJAX 4.0
Although the architectures depicted in Figure 1and Figure 2may look similar at first glance, they actually differ in
a number of key aspects.
First and foremost, with ASP.NET AJAX 4.0 you can build client-side data-binding solutions that work with any
modern browser. The glue code required to actually bind source data to target elements is now part of the Microsoft
Ajax JavaScript library. As such, it can be hosted in any browser.
Furthermore, for binding you no longer have proprietary and non-standard HTML attributes such as datasrc and
datafld that the browser must resolve. Instead, binding information is specified using XHTML-compliant,
namespaced custom attributes resolved by code in the JavaScript library. It can also be done imperatively.
8/12/2019 Looking Ahead to ASP
30/64
Old-Style versus New-Style
Another significant difference lies in the structure of the data source object. In old-style data binding, you use a sort
of black-box proxy that manages data retrieval for you. In ASP.NET AJAX 4.0, you dont need any such ActiveX or
binary components. All you need is a JavaScript object with the source data.
The built-in binding infrastructure links together fields on the JavaScript source object and elements of the DOM.
In ASP.NET AJAX 4.0, such a binding infrastructure is built into the Sys.UI.DataView component. Functionally
speaking, the DataView object operates in much the same way as the RDS control does in IE4-style client data
binding. It connects directly to a remote endpoint to get and expose data.
However, there are some differences. The DataView object is a client control entirely written in JavaScript that
requires no special support from the browser to run. As you can see, its quite different from the RDS ActiveX
control.
Moreover, the DataView control doesnt directly interface with a relational data source. Instead, it connects to any
JavaScript Object Notation (JSON)- or JSON With Padding (JSONP)-enabled service, such as a Windows
Communication Foundation endpoint, and exchanges data using JSON. The service can wrap any physical data store
(including a relational database) or even be a plain wrapper around an Entity Framework model. As Figure 2
illustrates, in ASP.NET AJAX 4.0 you can even have data binding in place without an outbound network connectionto the server. If, say, upon loading, a page downloads some data onto the client machine, you can have data binding
at work on locally cached data without any further roundtrip to the server.
A Brief Summary
In the October 2009 installment of the Cutting Edge column (msdn.microsoft.com/magazine/ee309508.aspx), I
covered the basics of data binding in ASP.NET AJAX 4.0 from a developers perspective. While you can still refer
to that article for deep coverage, Im going to provide here a brief summary of the most important programming
facts for client data binding.
In ASP.NET AJAX 4.0, client-side data binding can occur within a proper HTML template. A template is a DOM
tree decorated with the sys-template CSS attribute:
...
The sys-template is a conventional name for a user-defined CSS style that at the very minimum includes the
following:
.sys-template { display:none; }
Decorating a given HTML tag with the sys-template attribute is not enough, however. You must also add some
behavior to the tag that enables it to process any binding expressions inside. In this context, a behavior is just an
instance of a made-to-measure JavaScript component or control.
A behavior can be attached to an HTML tag, either by instantiating the behavior programmatically or by using a
declarative approach (by adding markup to the template tags in the page). For the declarative approach, the behavior
must be associated with a public name (namespace prefix).
Heres an example of assigning a public name to an instance of the DataView component:
http://msdn.microsoft.com/en-us/magazine/ee309508.aspxhttp://msdn.microsoft.com/en-us/magazine/ee309508.aspxhttp://msdn.microsoft.com/en-us/magazine/ee309508.aspxhttp://msdn.microsoft.com/en-us/magazine/ee309508.aspx8/12/2019 Looking Ahead to ASP
31/64
...
The sys:attach attribute gets a public name and creates an instance of the referenced behavior object. In the first code
example in this section, the DIV tag is empowered with the behavior expressed by the object named dataview1. As
you can guess, dataview1 is just the public name of the Sys.UI.DataView JavaScript object.
Once a DataView instance has been attached to an ASP.NET AJAX 4.0 template, the DataView can successfully
process any binding expressions contained in the templates. Heres a sample template with the simplest binding
syntax:
{{ Name }}
{{ Description }}
The {{expression}} token tells the DataView to process the embedded JavaScript expression and assign the result to
the DOM or the specified DataView property. For example, the code above assigns the content of a JavaScript
variable named imageArray to a DataView property named data. In this way, you define the data source of the
binding operation. This information is used to expand any other binding expressions within the template, such as
those used above in the body of the two SPAN tags. Name and Description are expected to be public properties on
the data item or items assigned to the data property of the DataView.
Inline Expression Evaluation
The {{expression}} syntax indicates the simplest type of binding supported by ASP.NET AJAX 4.0. Any bindings
expressed in this way are evaluated only when the template is rendered. They are never updated unless the template
is refreshed programmatically.
An inline expression is evaluated against the current state of the data source at rendering time, but doesnt
automatically capture any further changes made to the data source.
An alternative, richer binding model is also supported that gives you the same programming power of XAML data
binding in Windows Presentation Foundation and Silverlight applications. Such a set of advanced data binding
features are commonly referred to as live binding. Lets find out more.
Live BindingLive binding ensures that the value displayed in the user interface is automatically updated any time the bound value
in the data source changes. For example, suppose you establish a live binding between a SPAN tag and the
CompanyName property in a data source. The SPAN tag displays the current value of the CompanyName property
at the time of rendering. However, the content of the SPAN tag will be automatically updated any time the bound
data source property undergoes changes. Live binding can be applied to any two objects, whether DOM elements or
JavaScript objects.
A different syntax is required for live binding expressions. Heres an example:
8/12/2019 Looking Ahead to ASP
32/64
{binding CompanyName}
You use a single pair of curly brackets to wrap the expression, and prefix it with the keyword binding. As you can
see, the overall syntax has much in common with the equivalent XAML syntax, and that isnt coincidental.
It should be noted that the content of the SPAN tag shown earlier is updated whenever a change is detected on the
currently bound data item; the reverse wont work. If the content of the SPAN is updated, that change wont bepropagated to the source object.
Live binding also can be described as a one-way binding that may happen repeatedly as updates on the data source
are detected.
Hold on! The strategy employed to detect changes on bindings is a key point and Ill have more to say about it in a
moment, but not before introducing two-way binding.
Two-Way Data Binding
Two-way data binding is a special form of live binding that uses two channels to detect changes on the binding.
When two-way binding is in place between two objects, the following happens:
If the data source changes, the target object is automatically refreshed. If the target object changes, the new state is propagated to the underlying data source.Put another way, two-way data binding ensures that the source and target objects are always in sync.
No Tier Crossing
The following may perhaps sound like a foregone conclusion, but let me make it clear anyway. Imagine you have
two-way binding between a piece of user interface and some data that a service retrieved from a database.
The data downloaded from the server and bound to the visual elements of the user interface represent a snapshot of
the domain model. Say, for example, it represents a Customer object. If the displayed Customer object is modified in
a two-way binding page, then all detected changes are mirrored to the client-side Customer object, but in no way
will they be propagated to the server. Two-way data binding doesnt cross any tiers.
In terms of syntax, two-way binding is nearly the same as one-way live binding.
An ASP.NET AJAX binding is expressed via a Sys.Binding JavaScript object. You can control the direction of the
data flow through the mode attribute on the Sys.Binding object that the framework creates for you any time you use
the live binding syntax. (Note that no Sys.Binding object is created when you opt for plain {{...}} inline
expressions.)
The following code snippet shows how to set up two-way data binding using the mode attribute:
{binding CompanyName, mode=twoWay}>
Possible values for the mode attribute are summarized in Figure 3.
Member Value Description
auto 0 Data flow is twoWay if the target is an input element, select element,
textArea element or component that implements the
Sys.INotifyPropertyChange Interface. Data flow is oneWay otherwise.
oneTime 1 Data is transferred from the source object to the target only one time when
8/12/2019 Looking Ahead to ASP
33/64
the template is rendered.
oneWay 2 Data is transferred from the source object to the target whenever the source
is updated.
twoWay 3 Data is transferred from the source object to the target whenever the source
is updated, and from target to source whenever the target is updated.
oneWaytoSource 4 Data is transferred from target to source whenever the target is updated.
Figure 3 The Sys.BindingMode Enumeration
Live Binding in Action
Figure 4shows sample code that demonstrates live, two-way data binding. The page contains one template that is
rendered using a DataView control. The data source object is a JavaScript array named theCustomers. Dont be
fooled by the fact that theCustomers is a local object statically defined within the client browser. What really matters
is that theCustomers is ultimately assigned to the data property of the DataView object. The DataView object has arich programming interface that allows you to put into the data property any content, including content downloaded
from a Web service.
.sys-template { display:none; }
var theCustomers = [
{ ID: "ALFKI", CompanyName:
"Alfred Futterkiste" },
{ ID: "CONTS", CompanyName:
"Contoso" }
];
8/12/2019 Looking Ahead to ASP
34/64
ContentPlaceHolderID="PH_Body"
runat="server">
{binding ID}
Currently displaying...
{binding CompanyName}
Figure 4 Live, Two-Way Binding Sample
For each bound data item, the template emits an LI tag that includes a text box. The text box is bound to the
CompanyName property of the source. In the same template, a SPAN tag is also bound to the CompanyName
property of the source.
Note that live bindings are not limited to the template they belong to. You can have the same expressionsay,
{binding CompanyName}in two different templates. As long as the same data source object (or a compatible
object) is attached to both templates, the binding will always be correctly resolved. Figure 5shows the page in
action.
8/12/2019 Looking Ahead to ASP
35/64
Figure 5Live Binding in Action
Initially the text box and the SPAN tag contain the same data. However, at some point the user may start editing the
name of the company in the text box. Nothing happens until the user tabs out of the text box.
The editing phase is considered complete as soon as the text box loses focus. At this point, the two-way data bindingmechanism triggers and updates the underlying data source object. Because the SPAN tag is also bound to the same
data property through live binding, any changes are propagated.
To prevent the automatic update of the data source when an INPUT element is involved, you set the mode property
explicitly, as shown below:
Enter this change to the code in Figure 4 and see the difference.
Detecting Changes
When the mode property of a binding is not set explicitly, it takes the auto value as described in Figure 3. So when
you attach a binding to any HTML elements that refer to input scenarios (such as INPUT, SELECT or
TEXTAREA), the property mode defaults to twoWay. As a result, all the changes to the target made via the
browsers user interface are automatically transferred to the source.
Note that there are two variations of a oneWay binding. The standard oneWay binding detects changes in the source
and reflects them in the user interface. The alternate oneWayToSource does the reverse: it detects changes in the
target and reflects them in the source object. Try using the following code:
8/12/2019 Looking Ahead to ASP
36/64
The initial display of the page will contain empty text boxes. As you type, though, the new text is detected and
processed as expected.
The two-way data binding option is also the default option for any bound JavaScript object that happens to
implement the Sys.INotifyPropertyChange interface. (The interface is part of the Microsoft Ajax JavaScript library.)
When I first introduced live binding, I said that the target is updated whenever the source changes. The following
explains which changes the framework can detect and how.
HTML input elements fire standard events when their state is changed or, at a minimum, they notify when they enter
or exit an editing phase. Because these events are part of the HTML standard, any data binding solution based on
that standard will work on any browsers.
For an update to one side of the binding to be reflected in the other, it has to be done in a way that is possible to
detect. Suppose you have a binding where the source is a JavaScript array, as shown here:
{binding CompanyName}
Try to update the CompanyName property on an object within the array. The markup shows a button that if clicked
runs the enterChanges JavaScript function, shown here:
{binding CompanyName}
...
function enterChanges() {
theCustomers[0].CompanyName =
"This is a new name";
}
The enterChanges function updates the CompanyName property on the first object in the array. As you can see, thisclearly is an operation that updates the state of a bound object.
In the case of live binding, you should expect the SPAN tag to display the new value. If you try that, though, you
will see that nothing happens.
That is because there is no cross-browser way to be notified of updates occurring to a plain old Jav