asp:feature
LANGUAGES: C#
TECHNOLOGIES: User Controls | HttpModules
Mine the Starter Kits
Customize and extend Microsoft's free apps.
By Brian Noyes
In this article and in two more features planned for the next two issues of asp.netPRO, I'll take you on a mining expedition of the ASP.NET Starter Kits. The goal is to get you deep into the code and accelerate your ability to reuse and extend the applications. I'll focus on the most interesting parts of the design and code, and I'll introduce ways to integrate, re-create, or extend the capabilities of each kit for your own Web applications. In this article, I'll kick off the discussion by focusing on the Community Starter Kit, which demonstrates a unique approach to building dynamic content-driven and collaborative Web sites.
Develop a Sense of Community
The Community Starter Kit presents a way to build a Web application that exploits some of ASP.NET's best and newest capabilities. The kit demonstrates a collaborative, community-oriented Web site where users can read articles, download files, view images, learn about events, and access other types of informational content (see Figure 1). Users also can participate in the site by uploading files, participating in discussions, adding their own articles, and rating and commenting on content added by others. The kit includes authentication to enforce access controls, and it provides a sophisticated administrative interface for configurable customization of all the site's aspects. It also includes separate controls that let ISPs set up and manage multiple communities on a server from a single management interface.
Figure 1. Here is the Community Starter Kit home page. The kit
demonstrates a collaborative Web space you can reuse, adapt, or extend for your
own Web applications.
Great. So that's what it provides at the user/provider level. But what about you, the developer - what is here for you? The first thing you might notice when you start looking at the Community Starter Kit is it really has only one .aspx page, which has no content on it at all. How can that be? Well, the site is built based completely on an extensible and dynamically data-driven architecture. That ought to catch your development manager's attention, right? It's pretty cool, if a bit complex to decipher at first. Basically, the site consists of an HTTP module; a single ASP.NET page implemented entirely in the codebehind; a framework of classes representing the codebehind of all the controls that comprise the site; a set of themes that provide the HTML and ASP.NET control tags for those controls; and a database to store and provide content.
It all gels together like this. An HTTP module named CommunityModule intercepts every request that comes in to the site. The module parses out the requested URL to break it into information that determines what community, section, and page the user is requesting, and it also extracts the user identity for authentication and authorization purposes. Then, it stuffs all this information into the SectionInfo, PageInfo, and UserInfo classes, which the module puts into the HttpContext object's Items collection so the classes are accessible to any classes that get called further down the HTTP pipeline. The module then simply calls the one and only .aspx page in the application, communityDefault.aspx (see Figure 2). (By the way, there also is a communityDefault.asmx page, which lets you expose capabilities from your site as Web services, all using the same starter kit architecture.)
Figure 2. All requests processed by the Community Starter Kit are
intercepted by the CommunityModule HTTP module and rewritten to the
communityDefault.aspx page. The codebehind in that page builds the page
dynamically using a combination of static HTML, user controls, and data.
Once the request is transferred to communityDefault.aspx, the page's codebehind constructs the page returned to the user on the fly based on a combination of hard-coded HTML tags, user controls (.ascx files), and data from a database. The results of this construction process are sent back to the user in the response, and they are unaware that what they see is generated dynamically with no real, corresponding "page."
The other feature the site uses for extensibility and customization is the concept of "skins," which let you define your own look and feel as a theme. Skins provide a set of .ascx files containing the HTML and ASP.NET control tags that map to code-behind classes defined as part of the starter kit class library. For example, one of the main sections (think "page types") provided in the kit is a discussion area. The functionality of the discussion thread is based on a set of classes defined in the kit that derive from WebControl. These classes load the .ascx files dynamically to determine the layout, and they expect tags to be present with particular IDs in the .ascx file they're tied to. To create a new theme, you simply define the .ascx file that contains appropriate HTML and/or ASP.NET server controls with those control IDs.
Step Out on Your Own
The Community Starter Kit provides several ways to enhance your site or build one from the ground up. The first is that you could take the site exactly as it is, then customize the existing look and feel, graphics, and content to create your community site without writing a single line of code. (See the whitepaper for information on how to do this.)
But you likely will want to incorporate some, perhaps not all, of the kit's capabilities into an existing Web site. Or, you might want to add new functionality using the same dynamic construction approach. So let's look into several forms of extending the starter kit for your own purposes.
First, I will cover one of the simplest ways to extend the kit: Adding a new theme to the site so you can change the look and feel. Then, I'll briefly discuss how to add the Community Starter Kit to an existing site without disturbing your existing site architecture and pages. Finally, I'll show you how to add new functionality and controls to the starter kit, using the existing class library and request processing.
When you implement a new theme, you don't have to implement skin .ascx files for every single type of module defined in the kit you plan to include in your pages. If your theme fails to define a skin for a control, it will inherit the skin from the default theme.
To create a bare-bones theme, create a new folder under the Themes folder with the name of your new theme (for example, MyTheme). Then create a subfolder structure (see Figure 3). In the \MyTheme\Skins\PageSkins folder, create a Default.ascx file as an empty file and add to it the code shown in Figure 4.
Figure 3. This is the folder structure for a theme. If skin .ascx files
for each type of control are not found by the kit in your defined theme, the
files from the default theme will be inherited and used instead. This allows
you to define a new theme incrementally.
<%@ import Namespace="ASPNET.StarterKit.Communities" %>
<%@ Register TagPrefix="community"
Namespace="ASPNET.StarterKit.Communities"
Assembly="ASPNET.StarterKit.Communities" %>
<%@ Control Language="C#" %>
Welcome to my site
Runat="Server" ID="Userlogin1" /> Figure 4. Implement a minimal skin by defining the
code shown as the Default.ascx file in a custom theme. Then you can start
creating your own look and feel and layout for the starter kit's built-in
capabilities. To define your skin, simply start adding HTML and ASP.NET
server control tags to the page to define the look and feel. Without modifying
the kit's base classes, only one ASP.NET server control is absolutely required:
an Image control with an ID of "Logo". You'll also need to include, however,
the UserLogin and Content PlaceHolder controls, or else you will have no way to
log in and access the Administrative pages that let you customize the site. The
UserLogin control assumes the presence of the Content PlaceHolder control to
present the login controls, so those two go hand in hand. The CommunityDefault base class also looks for server
controls with IDs of content, txtSearch, lnkSearch, and Footer. Beyond that,
you may add to the Default.ascx file any HTML content or server controls you
wish. The page skin represents the overall layout of a page; most of the
system's skins are located in the ContentSkins folder and correspond to each of
the different section types of content that can be presented in the main
content area of the page (for example, discussions, photos, books, events, and
so on). The process is similar for customizing other skins -
locate the class that implements the codebehind of the control to which you
want to add a new skin, then define the .ascx code in your Theme folders
corresponding to the controls the codebehind will seek. Determining which
controls are required and where the corresponding codebehind class is located
in the \Engine\Framework classes can take some digging. Use the existing themes
and their skin definitions to identify the control IDs defined in a particular
control for which you want to create a skin, then use VS .NET to search for the
control IDs declared in the codebehind classes under the \Engine\Framework
folders. Integrate a Community Using the Community Starter Kit's built-in capabilities to
add community functionality to an existing Web site is a piece of cake - and
you don't have to modify the Web site one bit. You either can install the kit
and start adding references to the URLs defined for the kit to pages within
your Web site, or you can create another virtual directory as a subfolder of
your site pointing to the starter kit's root folder. (Note that you probably
will need to create a custom theme to make the kit pages look like they are
part of your site.) Finally, you might want to create a new type of control or
module that uses the same dynamic construction process the starter kit
provides. To do this, you need to implement a class that represents the
codebehind for the control that will present your new functionality, which will
need to derive from the starter kit's SkinnedCommunityControl base class. You
need to create a skin (an .ascx file) that provides the layout and presentation
of that new functionality using HTML and ASP.NET server control tags. Then you
need to make some database entries to make the new functionality accessible
from the existing site. Note that the whitepaper documentation refers to adding
new pages or controls in this fashion as "Creating New Modules." Be aware that
the documentation uses the term "module" in a general sense - this does not
refer to adding new HTTP modules to the application. As an example, you can implement a survey page that asks a
reader to complete a survey about the site. The survey presents a series of
questions stored in the database, allows the reader to answer those questions,
and thanks them for their input. A real implementation of this functionality
would probably store the results in the database when they are submitted and
offer a summary page that shows cumulative survey results. To implement this
sample functionality, create two new content controls - one for presenting the
survey and one for presenting the completion page to the user. Figure 5 shows a skeletal implementation of the UserSurvey
class, derived from SkinnedCommunityControl. Once the implementation of the
methods is filled in, you need to create a corresponding skin that lays out the
tags corresponding to the controls defined in the control class. If the control
uses a container control such as Repeater (as does this example), the skin also
will need to ensure the contained controls are defined. In the case of the
UserSurvey sample, this includes defining an ItemTemplate that contains a Label
control, named lblQuestion, and five RadioButton controls, named rb1 through
rb5. This article's downloadable sample code simply populates the control with
some statically coded questions defined in the control itself. A second control
is defined in a similar fashion for presenting the user with a "Thank You"
message after they have submitted their survey. In a real-world implementation,
you also would want to force the user to log in before accessing the survey
page, and you probably would pull the questions from the database. See the
starter kit modules code for accessing the Book page from the Book Listing page
for an example of how to force the authentication within the starter kit
classes. using System; using System.Web.UI; using System.Web.UI.WebControls; using ASPNET.StarterKit.Communities; namespace ASPNET.StarterKit.Communities.UserSurvey { public class UserSurvey
: SkinnedCommunityControl { // Declare the skin
.ascx file that // defines the layout
for this control string skinFileName =
"UserSurvey_UserSurvey.ascx"; // Declare the
controls that this uses in the skin Button btnSubmit; Repeater rptQuestions; Label lblSummary; TextBox txtComments; public UserSurvey() :
base() { // Assign a default
skin filename if (SkinFileName ==
null) SkinFileName =
skinFileName; } override protected
string SkinType { // Tell the
framework what kind of control this is get { return
"ContentSkins"; } } override protected
void InitializeSkin(Control skin) { // Use SkinnedCommunityControl.GetControl
to locate // expected controls
and connect to member control // references, then
set their values } protected override
void OnLoad(EventArgs e) { // Initialize member
variables from DB or other source } } } Figure 5. To create a control you can plug in as a new
module in the Community Starter Kit, you need to create a class derived from
SkinnedCommunityControl, override some of the base class methods and
properties, and provide a corresponding skin .ascx file. Once the classes and their corresponding skin .ascx files
are defined, you need to add them to the code base for the starter kit and
recompile it. I added them as a new folder, named Survey, under the Modules
folder in the starter kit's Engine section. The code is going to resolve the
classes at run time based on namespace, so where they are in the folder
structure is important only for project-management purposes. You then must add
some entries to the database so you can add a section for the survey. To do
this, add a row to the Community_PageTypes table that added the UserSurvey
control as a new Section page type, then add a row to the Community_NamedPages
table to add the SurveyThanks control as a new named page type. (You can find a
SQL script to run in Query Analyzer to add these rows in this article's code
download.) Finally, to present the survey as part of the site, you must log in
as Administrator, go to the Edit Sections interface, and add the Survey as a
new section so it is presented in the top-level menu. The readme file included
in this article's code download details all the steps necessary to integrate
the code. Now you know how to start using the Community Starter Kit
to implement collaborative functionality on your site and present dynamically
generated content. Get the sample code and go through the exercise of adding
the survey control to the starter kit to get a better idea of how this all
comes together. Up next: The Reports Starter Kit, which demonstrates several
techniques for building Web-based reporting applications, including graphical
and tabular reports of many forms. The sample code in this
article is available for download. Brian Noyes is an independent software consultant,
writer, trainer, and president of Software Insight (http://www.softinsight.com). He's
an MCSD with more than 12 years of programming, design, and engineering
experience. Brian specializes in architecture, design, and coding of
cutting-edge software systems, and he is a contributing editor for asp.netPRO and
other publications. E-mail him at mailto:[email protected]. ASP.NET provides a development platform for building complex
Web applications and services that is easy to learn and use. The sample code
and snippets that comprise the framework's SDK documentation can take you only
so far, however, in building real-world applications. To build enterprise-class
Web apps, you usually need more complex samples that not only demonstrate
specific coding techniques, but that also demonstrate Web application
architectures and design patterns you can adopt and reuse in your own
development. Most ASP.NET developers are familiar with the IBuySpy
store and portal sample applications that became available with the release of
the .NET Framework SDK 1.0, and many companies used these sample sites as a
template for building their own apps. With the release of ASP.NET 1.1, a whole
set of new ASP.NET Starter Kits will be released that demonstrate many
different techniques, architectures, and designs that potentially can save you
hundreds of hours of development time. The starter kits are available in beta
form now at http://www.asp.net
and work fine with version 1.0 of the framework as well. Each kit comes with full source code and some whitepaper
documentation to get started on your own. They also each come in SDK and VS
.NET versions - the former favors no codebehind, while the latter uses
codebehind and includes VS .NET projects to manage and explore the code. They
each come in VB .NET and C# variants as well. Each kit demonstrates a different
kind of Web application with a fully functional and fictional purpose. They are
designed so you can reuse them in multiple ways, including direct modification
of the kit's content to create your specific application, addition of new
capabilities or content based on the framework the starter kit provides, or
extraction of code portions to integrate into your own Web application code
base. Five starter kits currently are available. The Community
Starter Kit demonstrates a unique approach to building and managing an online
collaborative environment using dynamic content, including discussion threads,
articles, events, downloads, and the ability for users to comment and rate
content on the site. The Reports Starter Kit shows you how to create a site
that provides graphical and tabular reporting content for online analysis and
viewing of your business data. The Time Tracker Starter Kit demonstrates a
Web-based time-management application for tracking project hours from normal
browsers or mobile devices. Finally, the Portal and Commerce starter kits
closely model the IBuySpy portal and store, respectively, but they have been
modified and made more generic for direct reuse in your applications. Using the Community Starter Kit to create a
community-based site is not simply a concept; the Capital Area .NET User's
Group (http://www.caparea.net)
is actually doing it (see Figure A).
Scott Lock, Alex Minor, Hal Hayes, and I are completely rebuilding the group's
site using the Community Starter Kit. Rather than building a theme from scratch, we started with
one of the existing themes ("Eco" to be exact), and modified copies of the
existing skin files to achieve the look and feel for the site we wanted. From
there, we simply used the built-in administration interfaces to expel all the
sample site content and modules and replaced the content with information
migrated from the existing site. This was all done in under 12 hours. We also will create a couple of new Web Boxes. Web Boxes
simply are user controls (.ascx files) displayed by the WebBoxList control in
the kit wherever you place it in your page layout (the right margin in the
default theme). We will use these for gathering input from users on meeting
evaluations and suggested speaker topics. Eventually, we might add some custom
modules for other purposes as well. After familiarizing ourselves with the
Community Starter Kit, we found it would be perfect for what we need to do, and
the out-of-the-box functionality it delivers is more than a head-start on
setting up a site like this - the kit creators have run most of the race for
you. Tell us what you think! Please send
any comments about this article to [email protected].
Please include the article title and author. Explore the Starter Kits
Practice What You Preach
Figure A. Here is the home page for the Capital Area .NET User's Group,
which is using the Community Starter Kit to create a real-world community site.
The look and feel of this site was created by adding real content to one of the
kit's existing themes.