Академический Документы
Профессиональный Документы
Культура Документы
Magazine 2008
Magazine 2008
5 Cookbook
www.aspnetPRO.com
October 2008
Volume 7 Number 10 Solutions for Building Enterprise Web Applications
��������������������������������
����������������������������
�������������������������������
����������������������������������������������������������������������������������������
����������������������������������������
���������������������������������
�����������������������������������������������������������������������������
�������������������������������� ���������������������������������������������������
����������� ���������
�������������� �������������
���������������������������������������������������������������������������������������������
��������������������
�����������������������������
�����������������������������������������������������������������������������������
����������������������������������������
������������������������������
��������������������������������������������������������������������������������������
������� ���������������� �����������������������������������������������������������������
����������������
������������������������
���������������������������������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������
����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ���� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������
In This Issue
October 2008 | Volume 7 Number 10
Columns
�������������������������������������������
���������������
Upgrading your software doesn’t always entail a learning curve: Getting
��������������������������������������������������
credentials and sharing tokens in AJAX is much the same as in classic
������������������
Cover Stor y
Feature
8 Custom Criteria
One of the most time-consuming
tasks involved in building any 36 Convention Over Configuration: Part II
Emad Ibrahim wraps up his two-part series on how to create applications
application is the customization using ASP.NET MVC, jQuery, and AJAX.
of the different criteria pages
for the reports. In this article,
Carl Ganz, Jr. illustrates how to Reviews
centralize your reporting criteria
interface into one page and 44 CloserLook: DXperience Universal
DXperience includes components for developing Windows and ASP.NET appli-
cations. Focusing on the components designed for ASP.NET, Anand Naraya-
dynamically create report criteria
pages at run time using defini- naswamy reviews the first build of the 2008 series.
tions stored in a table.
Departments
6 Crossword Puzzle
by Ravi Nangunoori
47 Advertising Index
asp.netPRO Online
Here’s just some of the content that’s available only online at www.aspnetpro.com.
• “Dynamic Data with the Entity Framework in Medium Trust.” Don Kiely provides
workarounds for using Dynamic Data with the Entity Framework in medium trust.
• “Creating XBAP Poppers.” Alvin Bruney shows us how to create XBAP Poppers.
• You’ll also find additional book and product reviews, product announcements, and
more — and only available at www.aspnetpro.com.
4 5 DOWN
6 1. The keyword used in C# to call a member of
7
the current instance of a class.
Custom Criteria
Customize Data-driven Report Criteria Pages
O
ne of the most time-consuming tasks involved in
building any application is the customization of Column Name Data Type Description
the different criteria pages for the reports. This ReportID Int ID of report to which these criteria
article illustrates how to centralize your reporting criteria controls belong.
interface into one page and dynamically create report cri- ControlName Varchar Name of the control object using ‘txt’,
‘lst’, etc. prefix.
teria pages at run time using definitions stored in a table.
ParameterName Varchar Name of the report parameter to which
the entered value is assigned.
The controls typically required for criteria pages are
Label Varchar Text used to described the control on
text/numeric input boxes, date controls, checkboxes, list-
the Web page.
boxes, and comboboxes. Radio buttons are not necessary
because comboboxes can handle the same choices and Type Tinyint Enumerated value indicating the type of
are much easier to work with when using data-driven control: ComboBox, ListBox, etc.
programming techniques. DataSource Varchar Connection string for data-populated
controls.
As a general rule, date criteria should be set up in a
StoredProc Varchar Name of the stored procedure, the value
“from/to” layout specified by the user as a range. If a user column, and the description column
only needs one day’s worth of information, the “from/to” that populated the control separated by
dates can be set to the same date. If the particular param- semi-colons.
eter truly requires only a single date, then certainly offer DefaultValue Varchar Default value of the control.
the user only one date box. Your validation code should
preclude the user from entering a “from” date that is later Left Int Left position on the Web page.
than the “to” date (and any other such logical inconsis-
Top Int Top position on the Web page.
tencies). Optionally, the “to” date can be defaulted to the
system date as user needs require. Because there’s nor- Width Int Width position on the Web page.
mally very little free-form data you would pass to a report
engine, most of the error checking can occur before the Height Int Height position on the Web page.
user selections are submitted to the reporting tool.
Figure 1: Set the definitions for your criteria controls in a table.
Checkboxes handle Boolean values; textboxes can allow
the user to restrict the output based on free-form text the report could return “Smoot”, “Smith”, “Smythe”, etc.
— a last name, for example. Often you may wish to treat Depending on the flavor of SQL you are using, this can be
all entries in the textbox as partial search criteria. For accomplished by using the LIKE keyword and appending
example, if in filtering by last name the user enters “Sm”, a percent sign to the end of the search value:
N Se nd 3 n X fiel
centralize
EW cti 2 M d
Co
64 fice S W
O te
m
bi O o
VE n br it v sup omp
f M
pl
t a pe rd
e
o b L c
RS eak ersi po ati
IO s ons rt bilit
N
:
your word processing
y
���������� ��� 2 CREATE
print-ready
����������������
PDF documents
�������� �����������������
ê STORE
documents on a
server
7 EDIT
�������������� documents in a
�������������������������
browser
�������
TX Text Control ®
.NET Server 14.0
��� ������
SERVER-SIDE
��������������������������
• Create, modify and convert DOCX, DOC, RTF and HTML documents on a
central server
• Load and save MS Word documents including all merge fields
• Merge templates and create print-ready, password encrypted PDF documents
CLIENT-SIDE
• Edit documents directly in Microsoft Internet Explorer®
• Integrate a fully featured word processing interface, including headers and
footers, text frames, images, decimal tabs, section breaks and many more
© 2008 The Imaging Source Europe GmbH. All rights reserved. TX Text Control is a registered trademark of The Imaging Source Europe GmbH in the United States and/or other countries. All other names of actual companies and
products mentioned herein may be trademarks of their respective owners. Microsoft, Windows and Internet Explorer are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.
��������������������������������������������������������������������������������������������������
����������������������������������������������������������������������������������������������������
����������������
�������������������������������������������
�������������������������������������� ��������������������������������������������
�������������������������� ���������������������������������������
������������������������������������ ����������������
����������������������������� � ������������������������������������������
������ ���������������������������
�
���������������� ������
������
��� ��������������������������������������������������
������
���������������������������������
��������������������������������
����������������������������������
�������������������������������
�������������
������������������������������������������
�����������������������������������
������������
����������������������������������������
����������������������������
������������������������������
�����������������
��������������������
��������������������������������������
�������������������������������������
��������������������������������������
���������������������������������
�������������������������������������
������������������������������������������������������������
��������������������������������������������������������������������
CoverStory | Custom Criteria
oListBoxManager.Name = szControlName;
oListBox.ID = szControlName;
oListBox.Style["position"] = "absolute";
oListBoxManager.LabelControl =
oListBox.Style["left"] = iLeft.ToString() + "px";
AddDynamicLabel(szControlName, iLeft, iTop, szLabel);
oListBox.Style["top"] = iTop.ToString() + "px";
oListBox.Style["height"] = iHeight.ToString() + "px";
oListBoxManager.ListBoxControl =
oListBox.Style["width"] = iWidth.ToString() + "px";
AddDynamicListBox(szControlName, szDataSource,
oListBox.BorderStyle = BorderStyle.Solid;
szStoredProc, iLeft, iTop + 20, iWidth, iHeight);
oListBox.SelectionMode = ListSelectionMode.Multiple;
oListBoxManager.ButtonControl =
AddDynamicListBoxButton(szControlName, iLeft, Panel1.Controls.Add(oListBox);
iTop + iHeight + 20, iWidth, 23, szLabel);
return oListBox;
} }
Because every control has a name, and almost all have an The AddDynamicLabel method instantiates a Label object
associated Label control, these properties are encapsulated and assigns its location via the Style method (see Figure 5).
in the ControlManager base class from which the individual The new control is then added to the Controls collection of
control’s classes, like ListBoxManager and TextBoxManager, the owner Panel object, which displays it to the user.
inherit. To display the control, you must pass the control
name to the ShowListBox method (see Figure 4), along with Likewise, the ListBox control itself is displayed in a similar
the data source information, the dimensions of the listbox, fashion, as illustrated in the AddDynamicListBox method
and the caption. ShowListBox instantiates an object of type shown in Figure 6. The SelectionMode property is always set
ListBoxManager, which receives the instantiated objects of to multiple selections; otherwise, a combobox would suffice.
the Label, ListBox, and Button types. The szStoredProc parameter contains a semi-colon-delimited
return szResult;
The JavaScript ParseIt function shown in Figure 9 iterates
}
the ListBox and extracts the data.
Figure 9: The JavaScript ParseIt function.
The other controls are handled in a fashion similar to the
ListBox. Ultimately, the data definitions will produce the
screen shown in Figure 10.
B
ecause of the statelessness of the HTTP protocol, Authentication is a key feature in ASP.NET. It ensures
Web applications have a lot to gain from server- that only recognized users are granted access to a given
resource — be it a page, a folder, or a simple image.
side services that make up for the extreme Authentication is implemented through an HTTP module
simplicity of the protocol. On the other hand, the HTTP that intercepts any request to a protected resource and
protocol was designed for an idea of the Web quite differ- directs the user to a log-in page first. Are authentication
and other services compatible with ASP.NET AJAX?
ent from the one we have today. Such a simple protocol
was just fine for sharing HTML-based and hyperlinked How Authentication Works in ASP.NET
documents; it is less than ideal when we actually use In the configuration file in classic ASP.NET, you declare
which resources in which folder are off-limits for the anony-
HTML as an application delivery format and claim for mous user. At that point, the runtime pipeline automatically
security, state maintenance, and caching. At the end of redirects the anonymous user to a log-in page, where the
the day, though, HTTP is still there — and it forms the user is prompted for credentials. Next, if the user is success-
fully authenticated, an authentication token is generated as
foundation of ASP.NET and AJAX. a cookie and appended to the response. Finally, the user is
redirected to the originally requested page and passes any
To empower Web applications, virtually all server-side run- further check because of the attached token. Forms authenti-
time environments build an abstraction layer and provide cation is the ASP.NET built-in infrastructure that implements
additional services to applications, such as session state, the log-in pattern. Forms authentication requires an addi-
caching, user profiling, and, especially, authentication and tional log-in page and two HTTP redirect commands. Is it
role management. possible to save one redirect and authenticate the user from
within an HTML page through an AJAX call?
In ASP.NET, the vast majority of these application services
are incorporated in the runtime pipeline and use the HTTP An AJAX Infrastructure for Authentication
module infrastructure. Services intercept pipeline events For ASP.NET AJAX clients, the infrastructure for authentica-
and kick in when appropriate. The page developer isn’t tion consists of two key components: a client-side JavaScript
involved in the services activity and passively deals with class and a system-provided HTTP handler. The same model
the results of the activity itself. What does it mean? For is in place for other system services, such as role manage-
example, if a profiling service is in place, the page devel- ment and user profiles.
oper will find profile information for the current user ready
to use. The same goes for the role management service. The JavaScript class supplies one method to send any user’s
But what about authentication, instead? credentials to a server-side endpoint. The HTTP handler
isLoggedIn Boolean read-only property; indicates whether the Let’s focus on the login method. The first two arguments
current user is logged in. set the credentials of the user. When you authenticate a
path Gets and sets the URL to reach the authentication user through Forms authentication, a cookie is created
Web service. and attached to the response. This cookie is referred to
as the authentication cookie and its name defaults to
timeout Gets and sets the timeout for the user authentication
process.
.ASPXAUTH. The final Boolean argument indicates wheth-
er a persistent cookie is required. If so, authenticated
Figure 2: Properties of the Sys.Services.AuthenticationService object. credentials will be in a persistent cookie saved across
browser sessions.
internally invokes a system-provided scriptable Web service.
As a result, you receive a Boolean answer that indicates What about the expiration of the authentication cookie?
whether the user has been authenticated or not. The Web The cookie is simply given the expiration that you specify
service uses the server-side ASP.NET authentication and in the configuration file. So to set the timeout that is
membership API to validate the user information. When you appropriate for your site, you simply set the timeout
use a JavaScript proxy to command a remote authentication attribute in the <authentication> section of the applica-
service, you check your users more quickly because you tion’s web.config file to the desired number of minutes.
can incorporate a log-in form into any pages in the site that You should note that the authentication service sets the
users visit regularly. The authentication essentially consists cookie using the SetAuthCookie method on the Forms-
of a request, and doesn’t force a redirect to a specialized Authentication class. This means that most settings
log-in page. defined in the <authentication> section of the configura-
tion file are taken into proper account while creating the
From JavaScript, you invoke a proxy class implemented as a authentication ticket.
singleton. The original JavaScript class is instantiated in the
Microsoft AJAX client library and is exposed as an object (as The Role of Membership Providers
named here): Where would you specify the logic to check credentials? The
AJAX authentication service takes advantage of the currently
var proxy = Sys.Services.AuthenticationService; registered ASP.NET membership provider. The default mem-
nearly identical to any other JavaScript proxy public override bool ValidateUser(string username, string password)
class that the ScriptManager control generates for {
referenced Web and WCF services. The only dif- return AuthenticateUser(username, password);
}
ference is that such proxy classes for authentica-
tion, role management, and profile services are private bool AuthenticateUser(string username, string password)
natively part of the Microsoft client library and {
// Your authentication logic here
downloaded as part of the MicrosoftAjax.js file. }
The back-end of the authentication service is // Override all other abstract methods in MembershipProvider
:
implemented in the AuthenticationWebService }
class, marked as sealed and internal. The class
features a script service, as illustrated here: Figure 3: Skeleton for a custom membership provider.
You are not required to give an effec- Figure 4: Definition of the MembershipProvider class.
tive implementation to each member,
but at the very minimum you should day, this class is a relatively thin wrapper around
throw an exception, as shown here: MembershipProvider that overrides ValidateUser and
throws for any other method. You might seriously consider
public override bool ChangePassword(string username, deriving your custom provider class from this instead of
string oldPassword, string newPassword) MembershipProvider.
{
throw new NotSupportedException();
} Finally, to register the new membership provider, tweak the
web.config file as shown here:
For ASP.NET AJAX, though, there’s a quicker way out you
might want to consider. In the System.Web.ClientServices.- <membership defaultProvider="MyMembershipProvider">
Providers namespace you’ll find the ClientFormsAuthenti- <providers>
cationMembershipProvider class. This class is essentially <add name="MyMembershipProvider"
type="YourNamespace.CustomMembershipProvider" />
an implementation of MembershipProvider that ASP.NET </providers>
AJAX uses to perform default validation. At the end of the </membership>
�����������������������������������������������������������������������
�������������������������������������������������������������������������������������������
���������������������������������������������������������������������������
������������������������������ ���������������������������������������������������������������������������
� ���� � ����������������������������������
� ���� � �����������������������������
� ��������������������� � �����������������������
� ��������������� � ����������
� ��������������������� � ������������������
� ���������������������� � �����������������������������������
� ����������������������� � �����������
� ��������������������������������� � ���������������
� ����������
� ������������������������������������
����������������
����� ������ ����� �
� ���������������������
� ��������������������
������� ����� ����� � ���������������� � ������������������
� ������������ � ��������������
���������� ����������� ��������������� � �������� � ��������������������������������
���������������� �������������� �������������� � ������������������������� �����
��������������� ������������ � ���� � ���������������������������
��������� ��������������������������������� � �������������������������������������
�������� ������������ �
�������������������������������
� ��������� �
��������� ��������������� � �������������������������������� � ��������������������������������
��������� � ������� � ����
� ���������������������������� � ���
���������������
���������������������� � ������������ � ������������
CoreCoder | Authentication and AJAX
Add the preceding code to the web.config file under the button to your client user interface and bind it to the fol-
<system.web> node and you’re done. lowing JavaScript code:
<script type="text/javascript"> The function originates a redirect and a full page reload.
var username = $get("Login1_UserName"); The final response doesn’t include any more than the
var password = $get("Login1_Password");
authentication cookie.
function Login1_Click()
{ Brief Notes on AJAX Authentication
Sys.Services.AuthenticationService.login(
username.value, password.value, false, ASP.NET AJAX authentication needs to be explicitly
null, null, onLoginCompleted); enabled through a setting in the configuration file:
return false;
}
: <system.web.extensions>
</script> <scripting>
<webServices>
<authenticationService enabled="true" />
The authentication occurs asynchronously; when all is </webServices>
done, the callback (in this case, onLoginCompleted) is </scripting>
</system.web.extensions>
invoked to give you a chance to update the user interface.
What about the log-out process? To give users a chance In ASP.NET, forms authentication always sends credentials
to log out directly from the client, you must add another as clear text. This is nothing new, but a reminder is still
useful. For a number of security-related reasons, it is rec-
ommended that log-in forms be placed in pages you reach
through HTTPS. Clear text is not related to AJAX, but
using AJAX for authentication certainly makes it easier for
developers to place log-in forms everywhere.
Conclusion
Forms authentication is the mechanism in ASP.NET applica-
tions that allows you to show a log-in page in front of users
when they attempt to access a protected resource. In classic
O
ver the years, many Web development tasks have Present Purchases
become easier to implement. For example, HTML The BuyNow control has a nearly identical design and
a similar one-button user interface. It is intended to be
is generated with drag and drop simplicity, basic associated with a specific product or service so users may
state management is now virtually automatic, and user purchase it. Like the donation control, the user’s initial
profile data management is nearly as simple as getting and button click leads them through PayPal’s intuitive pay-
ment processing system. When the transaction is com-
setting variables. plete, PayPal provides multiple options for transferring the
flow back to your Web site and allowing your Web site to
One thing that remains relatively laborious, however, is verify the completed payment.
payment processing. In an attempt to quench the thirst
for simpler e-commerce capabilities, I’ve assembled two The default user interface of the Buy Figure 2: The Buy
ASP.NET Web controls that will empower any user to Now button is shown in Figure 2. An Now button allows
donate money or buy a basic product or service from alternative button image may be speci- a user to purchase
a particular product
your Web site. fied by adjusting the ImageUrl property.
or service.
In the following paragraphs I’ll show you how easy it is to Common Properties
use these controls from an ASP.NET application. Following The two controls present slightly different user interfaces
that, I’ll show you how the controls were designed so you to the user, but they share the same set of public proper-
can extend them or learn how to make similar Web controls. ties. Some of the properties are likely more relevant for the
Buy Now button than the Donate button, but all the prop-
Accept Donations erties can be useful for both controls in certain situations.
The Donate control allows users to give money in a simple
and intuitive way. When the user clicks it at run time, they are If you’re familiar with the standard ASP.NET ImageButton
led through PayPal’s payment system that accepts credit card control, you’ll find most of the properties to be familiar
payments and other common payment options. End users do because both controls ultimately inherit from it. Here I’ll
not necessarily need to be PayPal members, but Web sites will cover the unique properties the controls offer (see Figure 3).
need a basic account with PayPal in order to accept such pay-
ments. Setting up a PayPal account is free, although they typi- Perhaps the most important property is the BusinessEmail
cally take a small specified amount from each transaction as string. This must be set to the e-mail address associated
their fee. When the transaction is complete, users are option- with your registered PayPal account. If this property is
ally redirected automatically back into not set correctly, you will not receive payments that were
the specified flow of your Web site. intended for you.
The default user interface of the Donate Figure 1: The Donate The Price property is also of notable functionality. For
control provides a
button is shown in Figure 1. An alter- simple and familiar way
the Buy Now button you’ll almost certainly want to set
native button image may be specified for users to contribute this property to the amount of the associated product or
by adjusting the ImageUrl property. to your cause. service. For the Donate button, you might choose to leave
Invoice String Passthrough variable you can use to The Boolean RequireNote property can be set to true to
identify your invoice number for this force users to include a note along with their payment. The
purchase. default value of this property is false.
ItemName String Description of item. If omitted,
customers can enter an item name You can avoid having to manually collect shipping address
at time of purchase. information for purchases that must be physically shipped to
ItemNumber String Passthrough variable for you to track
a user simply by setting the Boolean RequireShippingAddress
purchases or donations, passed property to true. This will prompt PayPal to collect the ship-
back to you at payment completion. ping address information, thus simplifying your own input
requirements.
CurrencyCode String Defines the currency of the payment.
Default is USD.
Transaction Complete
Price Single The required payment amount. If you want the user to return to the flow of your Web site
(Leave blank to allow the user to
after they’ve completed their interaction with PayPal, you
choose the payment amount.)
must set the SuccessReturnUrl and FailReturnUrl properties.
PostReturn Boolean Return method GET or POST: the The SuccessReturnUrl property should be set to the absolute
FORM METHOD used to send data
public Web address of the page intended to accept the user
to the URL specified by the return
variable after payment completion. back into your site. If the user cancels out of the PayPal trans-
Default: false. action, the FailReturnUrl page accepts the redirection instead.
Figure 4: This is an example of one of the properties from the Figure 6: This is the complete code for the Donate class found in
aspaypal_base class. the file Donate.vb.
Imports System.ComponentModel
Imports System.Web.UI
<DefaultProperty("Price"), _
ToolboxData("<{0}:BuyNow runat=server></{0}:BuyNow>")> _
Public Class BuyNow
Inherits aspaypal_base
Dim u As String
u = "http://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"
Me.ImageUrl = u
Me.cmd = "_xclick"
Figure 5: Visual Studio’s Select URL dialog box. End Sub
End Class
ties, and explored much of the source code. If Me.CurrencyCode.Trim.Length > 0 Then
h = New HiddenField()
I encourage you to download the complete source code, h.ID = "currency_code"
h.Value = Me.CurrencyCode
available in both VB.NET and C#, to more thoroughly h.RenderControl(writer)
explore their inner workings. With this knowledge you can End If
extend these controls with custom functionality, or create
If Me.CustomData.Trim.Length > 0 Then
entirely new controls of similar design. </> h = New HiddenField()
h.ID = "custom"
C# and VB.NET source code accompanying this article h.Value = Me.CustomData
h.RenderControl(writer)
is available for download to asp.netPRO subscribers at End If
www.aspnetPRO.com/download.
If Me.NotifyUrl.Trim.Length > 0 Then
h = New HiddenField()
h.ID = "notify_url"
Steve C. Orr is an ASPInsider, MCSD, Certified ScrumMaster, h.Value = Me.NotifyUrl
Microsoft MVP in ASP.NET, and author of Beginning ASP.NET 2.0 h.RenderControl(writer)
End If
AJAX by Wrox. He’s been developing software solutions for leading
companies in the Seattle area for more than a decade. When he’s not If Me.FailReturnUrl.Trim.Length > 0 Then
busy designing software systems or writing about them, he often can h = New HiddenField()
h.ID = "cancel_return"
be found loitering at local user groups and habitually lurking in the h.Value = Me.FailReturnUrl
ASP.NET newsgroup. Find out more about him at SteveOrr.net or h.RenderControl(writer)
e-mail him at Steve@SteveOrr.net. End If
Workflow Services
Exploring .NET Framework 3.5 Features for Better
Workflow and WCF Integration
T
his monthly column explores how to expose work- tier to automate the flow of messaging between users,
flows as WCF services, and how to consume WCF applications, and services. For client applications to reach
a workflow, it is helpful to expose it as a WCF service —
services from workflows using features introduced either behind the firewall or on the Internet. In a service-
with .NET Framework 3.5. If you have questions about oriented system, business functionality is typically exposed
migrating your existing ASMX or WSE Web services to through services (for this discussion I’ll assume services
are implemented in WCF) — which means that a workflow
WCF, or questions regarding WCF as it relates to Web ser- is likely to coordinate access to that functionality by calling
vices, please send them to underthehood@aspnetpro.com! those services.
Workflow Services were introduced with the release of .NET Simply put, Workflow Services make it easy to expose a
Framework 3.5 to facilitate better communication between workflow as a WCF service so that client applications can
WCF and Windows Workflow Foundation (Workflow or reach it, and make it easy for workflows to call out to WCF
WF). Before this release it was cumbersome at best to start services to coordinate access to business logic in a service-
a workflow from a WCF service operation, or to call a WCF oriented system. The value Workflow Services bring to the
service operation from an executing workflow. The term table is in the removal of overhead to set up communica-
“Workflow Services” describes a workflow that is exposed tion between WCF and Workflow to accomplish these two
as a WCF service and can more easily make calls to other scenarios. Under the assumption you are employing work-
WCF services, thanks to a few new Workflow activities: flow in the middle-tier, Workflow Services become a staple
ReceiveActivity and SendActivity. Visual Studio templates item in your application.
simplify the process of creating a new Workflow Service by
generating sample sequential or state machine workflows Workflow Service Features and
along with related code and configuration. Templates
Creating a Workflow Service involves leveraging several
In this article I’ll explain how Workflow Services can be .NET Framework 3.5 features, including:
used to expose workflows as WCF services, and to consume § ReceiveActivity: A new Workflow activity that imple-
other WCF services — and why you would want to leverage ments a WCF service operation.
these features. I assume you have some basic understanding § SendActivity: A new Workflow activity for calling WCF
of Workflow technology, so I won’t be introducing you to services from an executing workflow instance.
Workflow concepts. § Context-aware bindings: New WCF bindings specifically
for Workflow, which handle workflow instance manage-
Why Workflow Services? ment between clients and Workflow Services.
Workflow is useful for describing and executing long- § WorkflowServiceHost: A new ServiceHost type that
running and complex business processes. Typically, we see facilitates communication between WCF services and the
Workflow technology implemented as part of the middle- Workflow Runtime.
����������������
������ ������������������������������������������������������������������
�����������������
�������������������������������������������������������
���������� �����������������������
��������������������������������������������������������������������������������
Exploring WCF Web Services | Workflow Services
IContextManager ctxManager =
Workflow Service Configuration m_proxy.InnerChannel.GetProperty<IContextManager>();
Once the Workflow Service design is complete, and service IDictionary<string, string> ctx =
contracts and operations are defined and associated with new Dictionary<string, string>();
ctx.Add("instanceId", this.m_instanceId);
ReceiveActivity instances, it’s time to think about Workflow
Service configuration. Because a Workflow Service is imple- ctxManager.SetContext(ctx);
mented as a WCF service, each service contract must have
at least one service endpoint defined so clients can com- Note: If the Workflow Service is configured to use Workflow
municate with the service. This is done with classic WCF Persistence Services, the workflow instance state can be
configuration settings — with the exception that it requires reloaded from the database. This makes it possible to sur-
the use of a special context-aware binding. The following vive service channel faults and machine restarts.
example illustrates a Workflow Service endpoint for the con-
tract defined in Figure 6 — using WSHttpContextBinding: ReceiveActivity Execution
The sequence contained within a ReceiveActivity is executed
<service name="SequentialWFService.WFService"> synchronously as part of the WCF service operation. Param-
<endpoint address="http://localhost:8000/WFService" eters passed to the operation can be used by the activities
binding="wsHttpContextBinding"
contract="IWFService"> in the sequence, and before the sequence ends the activity’s
</endpoint> return value or FaultMessage should be set. Activities that
</service> follow a ReceiveActivity in the workflow are executed
asynchronously to the client (because a response will have
There are three context-aware bindings introduced with .NET already been sent back as the ReceiveActivity terminates).
Framework 3.5: BasicHttpContextBinding, WSHttpContext-
Binding, and NetTcpContextBinding. Each binding includes a For the Workflow Service defined in Figure 4, the CodeActivity
context binding element to enable communication between executes before sending a response to the client. The following
clients and a specific workflow instance. code inside the CodeActivity sets the return value:
��������������������
���������� ������������������������
��������������������������������������������������������������������������������
Exploring WCF Web Services | Workflow Services
this.ReceiveOperation1Return = "ReceiveOperation1 called"; call out to WCF service operations without the hassle of
this.ReceiveOperation1Fault = null; prior techniques.
If an exception occurs and the workflow should be terminated, Using SendActivity, a Workflow Service can be config-
a fault can be thrown by initializing the FaultMessage property ured to call a particular WCF service contract by simply
through its bound field: providing the service contract metadata, indicating the
operation to call, binding parameters to workflow fields
this.ReceiveOperation1Fault = or properties, and providing a configuration for the cli-
new FaultException("ReceiveOperation1 has faulted."); ent proxy. The proxy is automatically generated based on
the information provided to the SendActivity, so it is not
Activities that follow a ReceiveActivity continue to execute necessary to write code to call the service unless you are
on the same thread as the ReceiveActivity — although a customizing the call to provide a dynamic address or spe-
response has already been sent to the client. cific security settings.
Note: Because activities placed within a ReceiveActivity are Figure 7 illustrates the same Workflow Service from Figure
executed synchronously to the client, care should be taken that 4 (modified to add a call to a WCF service operation within
this sequence is not long running in order to avoid timeouts. each ReceiveActivity). Think of this as the Workflow Ser-
Only those activities that contribute directly to the operation vice coordinating downstream service calls according to a
response need be part of the ReceiveActivity — the rest can be business process.
executed asynchronously with the remainder of the workflow.
As with ReceiveActivity, developers can configure each
SendActivity SendActivity by setting its properties. The key properties to
So far I’ve focused on Workflow Services as exposing WCF initialize are:
service endpoints to clients so they can invoke operations § ServiceOperationInfo: Indicates the service operation to
implemented by ReceiveActivity instances. Another impor- be invoked when the SendActivity instance is executed.
tant feature of a Workflow Service is the ability to easily This is set through the Choose Operation dialog box.
§ EndpointName: A child of the ChannelToken property
that specifies the WCF client configuration section to use
����������������� for proxy initialization. This can be shared by several
���������������� SendActivity instances by using the same ChannelToken.
����������������� § (ReturnValue): Associates the SendActivity return value
with a field or property of the workflow. Developers can set
���������������������
���������� ���������������������������
��������������������������������������������������������������������������������
Exploring WCF Web Services | Workflow Services
Figure 8 illustrates
the property values of
the first SendActivity
instance.
To configure each
SendActivity requires
access to the service
Figure 9: Selecting a service contract to be used for SendActivity
contract and any instances.
custom data types Figure 8: SendActivity properties for
Operation1.
relied upon by that enough to reflect the workflow definition for this contract
contract. The easiest way to gain access to this is to either (because it is not statically defined).
generate a proxy, or, if you own both projects, you can share
a metadata assembly between the Workflow Service project To host Workflow Services in IIS or WAS, use the Workflow-
and the service project(s). Once this metadata is available to ServiceHostFactory in the .svc declaration (full name required):
the project you can select the service contract and operation
to associate with a SendActivity instance. After importing the <%@ ServiceHost Service="SequentialWFService.
service contract (see Figure 9) the same Choose Operation WFService" Factory="System.ServiceModel.Activation.
WorkflowServiceHostFactory" %>
dialog box from Figure 6 is presented to select the operation
for the SendActivity being configured.
Next Up: Workflow Services and Security
SendActivity instances also require access to a <client> In this article I introduced the Workflow Service, explained how
configuration section specified in the EndpointName prop- to set up ReceiveActivity and SendActivity, and explained how
erty. This configuration, which is usually created through the hosting model ties it all together. I have purposely left out
proxy generation, must be part of the host process configu- security features for Workflow Services as that topic requires an
ration file. To set the address of the service to be called by a article of its own. So, stay tuned to the next issue for the contin-
SendActivity instance, set the CustomAddress property. uation of this discussion of Workflow Services as I explain your
options for securing ReceiveActivity and SendActivity. </>
WorkflowServiceHost
WorkflowServiceHost is an extension to ServiceHost (the type Download the samples for this article from www.dasblonde.net/
responsible for initializing WCF communication channels at downloads/aspprooct08.zip.
the service). WorkflowServiceHost adds functionality to facili-
tate communication between WCF and Workflow. When a
request is received at a ReceiveActivity, the WorkflowService-
Host ensures the Workflow Runtime is initialized, initializes a Michele Leroux Bustamante is Chief Architect of IDesign Inc., Microsoft
new workflow instance if necessary (and if supported by the Regional Director for San Diego, and Microsoft MVP for Connected
ReceiveActivity), then handles activating the workflow. For Systems. At IDesign Michele provides training, mentoring, and high-
SendActivity instances, the WorkflowServiceHost constructs a end architecture consulting services focusing on Web services, scalable
client channel (or proxy) to call the specified service operation. and secure architecture design for .NET, federated security scenarios,
Web services, interoperability, and globalization architecture. She is
To host a Workflow Service, construct the WorkflowService- a member of the International .NET Speakers Association (INETA),
Host as follows: a frequent conference presenter, conference chair for SD West, and is
frequently published in several major technology journals. Michele
WorkflowServiceHost hostWFService = new also is on the board of directors for IASA (International Association
WorkflowServiceHost(typeof(SequentialWFService.WFService)); of Software Architects), and a Program Advisor to UCSD Extension.
hostWFService.Open();
Her latest book is Learning WCF (O’Reilly, 2007); visit her book blog
If the workflow-first approach was used to generate at www.thatindigogirl.com. Reach her at mlb@idesign.net, or visit
the WCF contract, the WorkflowServiceHost is smart www.idesign.net and her main blog at www.dasblonde.net.
�������������������������������
���������� �����������������������
��������������������������������������������������������������������������������
a s p: F ea t u re
LANGUAGES: C# | VB.NET § ASP.NET VERSIONS: 3.5
§ By Emad Ibrahim
Convention Over
Configuration
Creating Applications Using ASP.NET MVC,
jQuery, and AJAX: Part II
A
s is the nature of working with bleeding-edge Let’s create the view by adding a new MVC View Content
“preview” technology, you are bound to bleed Page and using the Site.Master page in the Views | Shared
folder as the master. Run the project (Ctrl+F5) and navigate
once in a while. A lot has changed since Part to http://localhost:9055/listing/new (you should get a blank
I of this article was written. Preview 4 of ASP.NET MVC content page). We need to collect a title, description, and
was released and now we have to change some of our image on this page, so let’s add all the necessary controls
and a Submit button. The HTML is shown in Figure 2; the
code. The code changes are minor, but the new project form is shown in Figure 3.
template includes views and code to log in, register, and
log out. Although these pages don’t use AJAX, it would When the user clicks the Submit button, we want to
perform some basic validation on the client (JavaScript),
be easy to AJAX-enable them. For the sake of simplic- submit the request using AJAX to create the listing, then
ity, I am going to start with a new project using the new upload the image.
template (see end of article for download details).
<Authorize()> _
Public Function [New]() As ActionResult
Return View()
Let’s say we are building a classifieds Web site similar to
End Function
craigslist. The first thing we’ll do is enable the user to list
an item for sale. A listing is made up of a title, description, Figure 1: Controller action to render the new listing view.
and, optionally, an image. First, let’s create a new control-
ler named ListingController and add a “New” action. This <fieldset>
action only needs to render the view for creating a new <div class="label">Title <span class="validation"
listing (see Figure 1). id="valTitle"></span></div>
<%=Html.TextBox("txtTitle", New With {.style =
"width:300px"})%>
Notice that we don’t tell it which view to render; instead, <div class="label">Description <span class="validation"
it will automatically look for the view with the same id="valDescription"></span></div>
<%= Html.TextArea("txtDescription","",8,50) %>
name as the action (“new”). It will look for new.aspx or <div class="label">Images <span class="validation"
new.ascx in the Views | Listing folder, then it will look id="valImage"></span></div>
in the Views | Shared folder. Alternatively, you could call <form enctype="multipart/form-data" method="post"
name="formImage" id="formImage">
View(“new”). Also note the Authorize attribute; this is <input type="file" id="fileImage" name="fileImage"/>
new to Preview 4 and it’s the quickest way to authorize </form><br />
an action. By adding this attribute, only a logged-in user </fieldset>
<p><input type="button" id="btnSubmit" name="btnSubmit"
will be allowed to run it. If you are not logged in, you’ll onclick="submit();" value="Submit" /> </p>
be directed to the log-in page. All this is done automati-
cally, starting with the Preview 4 version. Figure 2: HTML for the create listing view.
validation method
if($("#txtTitle").val().length == 0) {
is shown in Figure 4 $("#valTitle").html("* Title is required").show();
(the image validation var isvalid = false;
Figure 3: The create new list page. }
method is shown in
Figure 5); note the use if($("#txtDescription").val().length == 0) {
of the jQuery methods: $("#valDescription").html("* Description is
required").show();
§ val to get the value of the element
var isvalid = false;
§ hide to hide the matching elements }
§ html(“some html string”) to set the html of the element return isvalid;
}
§ show to display the matching elements
Figure 4: JavaScript to validate a page.
As discussed in Part I, we are using jQuery to select and
manipulate DOM elements. We first hide all spans with line will select the element named “aDiv”, change its HTML
a validation class, then check the title, description, and content to “hello world”, then hide it slowly, then show it
image and display the appropriate error message. If every- fast. Each method basically returns an object that the follow-
thing checks out, we return true. Note the method chaining ing method acts upon to create a chain of method calls.
that makes jQuery very powerful and easy to use. Chaining
allows you to do things like $(“aDiv”).html(“hello world”).- Now that the form is valid, we need to submit it (see Figure
hide(“slow”).show(“fast”). This seemingly simple JavaScript 6). We’ll submit the form to /listing/create, so we’ll need
Visit us online at
Co-Sponsored by: www.aspnetPRO.com/cd
or Call Toll-free in the U.S.
(800) 884-6367
Outside the U.S. dial (916) 379-0609
* Free Shipping and Handling to US and Canada! All other countries US$10.00 for shipping and handling. Applicable sales tax will be added for California residents. Payment must
be in US dollars drawn on a US bank. Your purchase may be tax deductible if used for business purposes. Please check with your tax advisor.
Microsoft and ASP.NET are registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries
and are used by ICG under license from owner. asp.netPRO and Informant are trademarks or registered trademarks of Informant
Communications Group, Inc.
Figure 15: The controller action to render the list of listings view.
$(document).ready(function() {
$("div.listingRow").hover(
function(){$(this).css("backgroundColor", "yellow");},
Figure 11: A grid displaying the listings. function(){$(this).css("backgroundColor", "");}
);
});
<% For Each item In ViewData.Model.Items%>
<div id="div<%= item.Id %>" class="listingRow">
Figure 16: The JavaScript function to initialize the page.
<span>
<%=Html.ActionLink(Of ListingController)(Function(c)
c.Edit(item.Id), "edit")%> To render a view with a strongly typed model, call
<a href="#" onclick="deleteItem('<%= item.Id %>') View(“list”, model) instead of View(“list”). If the view name
">delete</a> </span>
<%= item.Title%>
is the same as the action, you can simply call View(model).
</div> To see it how it all works together, take a look at the List
<% Next%> action in Figure 15.
DXperience Universal
How Suite It Is
M
any companies have released a range of nents, and allows developers to build and maintain business
products rolled into a .NET suite for applications with ease, thereby drastically reducing time to
develop solutions for end users.
Windows and Web development. These
products not only simplify programming tasks, they The ASP.NET components are bundled into various suites:
also provide components that can be used to deliver ASPxGridView, ASPxperience, ASPxScheduler, ASPxSpell,
and ASPxHTML Editor. The ASPxperience suite includes a
cutting-edge interfaces and instantly modify the look set of 20 controls. A notable feature is the inclusion of a
and feel of an entire application. DXperience Universal cloud/tag control, which I hope will be useful during the
from Developer Express (DevExpress) is one such prod- development of a knowledge base or a content manage-
ment application.
uct (www.devexpress.com/Products/NET/DXperience/
editionUniversal.xml). DXperience includes a plethora DXperience ships with a new rich text editor for ASP.NET
of components for developing highly powerful Windows 2.0, built entirely with the ASPxperience Suite with the
integration of ASPxUploadControl for embedding images.
and ASP.NET applications. I reviewed the first build of It includes the newly released AJAX-based ASPxTreeList
the 2008 series, which contains tons of feature enhance- control, which has numerous performance optimization
ments, focusing mainly on the components meant for features. It enables developers to render paged and hierar-
chical TreeLists, along with many other options (see Figure
ASP.NET applications. 1). The data loads quickly because of the powerful built-in
AJAX capabilities.
I tested the product on a machine loaded with Windows XP
Service Pack 2 with 512 MB of RAM. The installation pack- The latest build includes improve-
age was around 150 MB; I downloaded it within 20 minutes ments for the ASPxGridView,
using a broadband connection. DevExpress deserves special ASPxPivotGrid, and ASPxScheduler
credit as they have created a user-friendly installer with suites, in addition to several suites
easy to understand instructions. It automatically creates the oriented for the development of
required items on the Start menu and adds the controls to Windows-based applications. A
the Visual Studio Toolbox. complete list of all the new features
is located at www.devexpress.com/
DXperience ships with numerous controls that can be used Products/NET/DXperience/
not only to develop Windows and Web-based projects, but WhatsNew2008v1. Moreover,
also to include libraries for developing applications that DevExpress has made available
make use of reports and charts in addition to IDE produc- for the entire ASP.NET product
tivity and ORM tools — CodeRush and eXpressPersistent line more than 10 popular theme
Objects, which I hope will be useful for advanced develop- styles, which I feel is a big bonus
ers. DevExpress also provides a product named eXpressApp for developers, as they can develop Figure 1: Easily select
Framework (www.devexpress.com/xaf) that leverages and applications with a uniform an item using the
exploits their rich set of presentation and reporting compo- look and feel. TreeList control.
The column headers can now be displayed as filter drop- XtraReports comes with a full-blown designer, as well as the
down buttons with the help of the Header Filter feature ability to create subreports. It seamlessly integrates with Visual
included with the current build. This feature enables a user Studio, with support for Mail Merge, Master-Detail, Data Filter-
to dynamically filter a column based on a unique value ing, and Grouping. It ships with lots of native controls, such
(see Figures 2 and 3). It also reduces the search time for as Label, Line, BarCode, CheckBox, PageInfo, Panel, Picture-
locating specific data from the Grid for large databases. I Box, PageBreak, Table, and ZipCode, along with an enhanced
was amazed to see that I was able to implement this func- RichText control and Report Explorer. XtraReports enables you
tionality directly from the Properties window. to integrate your reporting applications with the XtraReports
Toolbar from within the Visual Studio IDE, as well as preview
There is absolutely no need for developers to write a sin- the generated report before its distribution. A notable feature is
gle line of code for performing standard tasks. However, that it ships with a report wizard that guides you in the report-
coding may be required for advanced projects (depending creation activities.
on the nature of the application being developed). The “DXperience Universal” continued on page 47
next component in my pipeline was Menus. I was able to
design a simple menu by making use
of the various styles. A key feature
is that menu items and correspond-
ing URLs can be directly added from
within the smart tag, and the required
changes are reflected immediately.
O
ne reason I often buy a book is because it solves rules. Chapter 8 has complete coverage of data binding in
a particular problem I am having writing an both Web Forms and Windows Forms. Chapter 9 covers XML
data, including schemas, XPath, and SQL Server XML data.
application; solving one problem in the middle of
a project can easily be worth the price of a book (which is Chapter 10 shows how to optimize data access in .NET
why I like the whole O’Reilly series of Cookbooks). with examples of executing multiple commands on a single
connection, bulk loading and copying, batch updates, and
working with large data from Oracle databases.
For example, let’s look at the first “recipe” in Bill Hamilton’s
ADO.NET 3.5 Cookbook, “Storing Connection Strings.” If Chapter 11 explains how to work with database metadata,
you are new to .NET database programming (and maybe including retrieving metadata, and information on columns
even if you are not so new), you need to know how to store (length, default types, etc.). It details how to retrieve a SQL
database connection strings. In .NET you have a number of Server query plan (I didn’t know you could do that with
options as to where to store connection strings. What are software). It shows how to create new databases and add
they, and which one is right for your situation? This recipe tables and relationships to a database. It continues with how
covers storing connection strings in the application, the reg- to enumerate different types of data providers (.NET, OLE
istry, Universal Data Link files (UDL), and custom files. This DB, ODBC, SQL), and closes by showing how to program-
section explains the advantages and disadvantages, security matically change SQL Server passwords.
ramifications, and ease of modifying each; it also provides
detailed instructions on how to use each of the preferred The final chapter covers CLR integration, which allows the
options. The book continues to do this for more than two use of .NET inside SQL Server, such as using C# or other
hundred recipes divided into twelve chapters. .NET-compatible languages to create stored procedures.
The book ends with an appendix that lists the changes in
The first chapter covers connecting to databases, including ADO.NET since version 1.0.
connecting to databases using Excel and text files, and how
to use connection pooling. Chapter 2 details working with This Cookbook has an incredible 900+ pages of short
disconnected data objects. Chapter 3 goes over retrieving examples showing how to perform specific tasks. If you are
data from databases, including hierarchical data; reading an experienced ADO.NET programmer, this book will pay
data from databases, text files, and Excel worksheets; and for itself many times over by speeding you through every-
querying using LINQ. Chapter 4 explains how to search day tasks. If you are learning ADO.NET, the best way is
and analyze data, including sorting, filtering, recursive by writing ADO.NET code — this book will keep you from
queries, and even how to access deleted rows (but only getting stuck by showing not only the how, but the why
before AcceptChanges is called). Chapter 5 covers adding of coding ADO.NET. Regardless of your skill level, this is a
and modifying data. book you cannot afford to be without. </>
8
T O
9 10
S E L E C T E D I T E M (depending on their skill level). Depending on the creativity
P A N E L I M
U R
11
X H T
12
M L L
and imagination, a developer can build any type of applica-
T
13
P R O X Y T A
14
B I R E A K P O I N T S tion, be it pure Windows-based word processing software or
C
15
O T I U
16
E
an ASP.NET-based online invoicing system. </>
A P R E C O M P I L A T I O N L X
C M H L I T
17 18 19
H E T R A C E D A T A S E T W Anand Narayanaswamy, a Microsoft Most Valuable Professional
E S N T E R
20
(MVP), works as an independent consultant based in Trivandrum,
S D I S P O S E D E X I
21
L O C A L S L N T T
India. Anand also works as chief technical editor for ASPAlliance.com.
22
G R E S O U R C E E M E He is the author of Community Server Quickly (www.packtpub.com/
23 R O
O D E D O M R R
C
community-server/book). He runs www.learnxpress.com,
S D
E www.dotnetalbum.com, www.csharpfaq.com, www.computerbook-
reviews.org, and www.devreviews.com. Find out more about him at
www.visualanand.net. He can be reached at visualanand@gmail.com.
asp.netPRO is published monthly by Informant Communications Group, Inc., 5105 Communications Group, Inc. asp.netPRO is a publication of Informant Communications
Florin-Perkins Road, Sacramento, California, 95826-4817. Basic one-year subscription Group, Inc. and is not sponsored by or affiliated with Microsoft Corporation. Microsoft is
rates: U.S. $34.99, Canada $44.99, all other countries $79.99, must be prepaid in U.S. not responsible in any way for the editorial policy or other contents of this publication.
dollars drawn on a U.S. bank. Printed in the USA. We welcome your comments and suggestions about the content of asp.netPRO, as
Postage paid at Elk Grove, CA and additional mailing offices. POSTMASTER: Send well as your commentary on the subject of ASP.NET development. We reserve the right
address changes to asp.netPRO, 5105 Florin-Perkins Road, Sacramento, California, to edit all submissions. Letters should include your name and address. Please direct all
95826-4817. Post International Publications Mail Product (Canadian Distribution) Sales letters to asp.netPRO, ATTN: Letters, 5105 Florin-Perkins Road, Sacramento, California,
Agreement No. 40028783. Subscription inquiries and orders should be directed to the 95826-4817. Letters may also be sent via e-mail to letters@aspnetPRO.com.
Circulation Department, asp.netPRO, 5105 Florin-Perkins Road, Sacramento, California, Informant is a registered trademark of Informant Communications Group, Inc., Elk
95826-4817, Phone 916-379-0609, Fax 916-379-0610. Code listings may be downloaded Grove, California. Microsoft and Visual Basic are trademarks of Microsoft Corporation
from the asp.netPRO Web site at www.aspnetPRO.com. and asp.netPRO is used by Informant Communications Group, Inc. under license from
Informant Communications Group, Inc. assumes no responsibility whatsoever for owner. Windows is a trademark of Microsoft Corporation. All other products men-
the uses made of any software code in this issue, whether modified or not. Informant tioned within are trademarks of their respective owners.
Communications Group, Inc. will not be liable for special, incidental, consequential, Microsoft, Visual Basic, Visual Studio, MSDN, ASP.NET, and the Visual Studio, .NET,
indirect, or other similar damages, even if we have been advised of the possibility of such Microsoft Office, and Visual Basic Logos are registered trademarks or trademarks of
damages. In no event will our liability for any damages to you or any other person ever Microsoft Corporation in the United States and/or other countries and are used by
exceed the price paid for your subscription to asp.netPRO, regardless of any form of the LICENSEE under license from owner. asp.netPRO, C# PRO, Informant, Microsoft Office
claim. Editorial contained within does not necessarily reflect the opinions of Informant Solutions Conference, and ASP.NET and XML Web Services Solutions Conference are
Communications Group, Inc. Informant Communications Group, Inc. assumes no respon- trademarks or registered trademarks of Informant Communications Group, Inc.
sibility for the products or services advertised within this publication. Writers interested in having works published in asp.netPRO may obtain a style guide
Copyright©2008 Informant Communications Group, Inc. All rights reserved. No part of by e-mailing David Riggs at driggs@informant.com. For direct mailings/e-mailings to
this publication may be reproduced in any way without the written consent of Informant our subscriber list please contact Rich Parker at rich@directmedia.com.
U
nless you’ve been living in Antarctica for the lot bigger than the United States). Microsoft is doing a pretty
past year or so, you’ve undoubtedly heard of decent job of putting Silverlight applets on many of their
Web properties, but most of those don’t have broad appeal
Microsoft’s dynamic new cross-platform Web beyond software developers and business users. What
development and video streaming technology, Silverlight, surprises me greatly is that MSN Video (e.g., SoapBox) is
which is based on Windows Presentation Foundation still powered by Flash. In my opinion, Microsoft should be
pushing to re-deploy MSN Video powered by Silverlight as
(WPF). I’ve noted several times in this column that soon as possible. Even though Silverlight 2.0 is still in beta,
Silverlight stands to play an important role in the future if it can power NBCOlympics.com, I’m confident that MSN
of Web development. That is, if it catches on. Video won’t be any trouble.
��������������� �����������������
���������������������������� �����������������
������������������ ����������������������������������������������������������������������������
����������������������������������������������������������
�����������������������������������������������������������������������������������������
����������������������������������
��������������������������������������
������������������������������ ������������������������������������������������
��������������������������������������������� ����������������������������������������������
���������������������������������������������� ������������������������������������
������������������������������������������ ����������������������������������������������������
�������������������������������������
�����������������������������������������
��������������������
�������������������������������
����������������������������������������������������
���������������������������������������������������
��������������������������������������������������������������
�������������������������������������
������������������������������������������������������������
���������������������������������������������������������
�������������������������������������������������
��������������������������������������������������
���������������������������������������������������������������������
������������������������������������������������������������������������������������������������������������������������
������������������������������������������������������������������������������������������������������������������
�����������������������������������������������������������������������������������������������������������������������
�����������������������������������������������������������������������
����������������������������������������������������
��������������������������������������������������������������
�����������������������������
� ���������������������������������������������������������������
� ��������������������������������������������������������
� ����������������������������������������������������
�����������������
� �����������������������������������������������
����������������������������
������ ��� �����������������������
������������� ����
� �����������������������������������������������������������������
����������������������������
������������������������� �������������������������
�������������������������������������������������
���������������������