Disadvantages of the SqlDataSource
As you have seen, when you use the SqlDataSource control, you can often avoid writing any data access
code. However, you also sacrifice a fair bit of flexibility. Here are the most significant disadvantages:
❑ Data access logic embedded in the page:To create a SqlDataSource control, you need to
hard-code the SQL statements in your web page. This means that you cannot fine-tune your
query without modifying your web page. In an enterprise application, this limitation is not
acceptable, as it is common to revise the queries after the application is deployed in response to
profiling, indexes, and expected loads. You can improve this situation a fair bit by restricting
your use of the SqlDataSource to stored procedures. However, in a large-scale web applica-
tion, the data access code will be maintained, tested, and refined separately from the business
logic (and it may even be coded by different developers). SqlDataSource just does not give
you that level of flexibility.
❑ Maintenance in large applications: Every page that accesses the database needs its own set of
SqlDataSource controls. This can turn into a maintenance nightmare, particularly if you have
several pages using the same query (each of which requires a duplicate instance of the
SqlDataSource ). In a component-based application, you will use a higher-level model. The
web pages will communicate with a data access library, which will contain all the database
details.
❑ Inapplicability to other data tasks: The SqlDataSource does not properly represent some
types of tasks. The SqlDataSource is intended for data display and data-editing scenarios.
However, this model breaks down if you need to connect to the database and perform another
task, such as placing a shipment request into an order pipeline or logging an event. In these sit-
uations, you will need custom database code. It will simplify your application if you have a sin-
gle database library that encapsulates these tasks along with data retrieval and updating
operations.
Although the SqlDataSource control is powerful, there are a number of other data source controls that
might better suit your specific data access scenario. One such control is XmlDataSource control, which
is the topic of focus in the next section.
Disadvantages of the SqlDataSource in ASP
Labels: Advanced, ASPData Source Controls in ASP
Data Source Controls
In ASP.NET 1.x, you typically performed a data-binding operation by writing some data access code to
retrieve a DataReaderor a DataSetobject, then you bound that data object to a server control, such as
a DataGrid , DropDownList, or ListBox. If you wanted to update or delete the bound data, you were
then responsible for writing the data access code to do that.
ASP.NET 2.0 introduces an additional layer of abstraction through the use of data source controls. The
data source controls abstract the use of an underlying data provider, such as the SQL data provider or
the OLE DB data provider. This means that you no longer need to concern yourself with the underlying
complexities of using the data providers. Instead, the data source controls do all the heavy lifting for
you. All you need to know is the location of your data and, if necessary, how to construct a query for
performing CRUD (create, retrieve, update, and delete) operations.
SqlDataSource Control
The SqlDataSource control is the data source control to use if your data is stored in a SQL Server,
Oracle Server, ODBC data source, OLE DB data source, or Windows SQL CE Database. The
SqlDataSource represents a database connection that uses an ADO.NET provider. However, this has a
catch. The SqlDataSource needs a generic way to create the Connection, Command, and DataReader
objects it requires. The only way this is possible is if your data provider includes a data provider factory,
which has the responsibility of creating the provider-specific objects that the SqlDataSource needs in
order to access the data source.
As you know, .NET ships with these four provider factories:
❑ System.Data.SqlClient
❑ System.Data.OracleClient
❑ System.Data.OleDb
❑ System.Data.Odbc
These are registered in the machine.config file, and as a result you can use any of them with the
SqlDataSource . You specify the provider name as part of the SqlDataSource control declaration. Here
is a SqlDataSource that connects to a SQL Server database:
The next step is to supply the required connection string — without it, you cannot make any connections:
Once you have specified the provider name and connection string, the next step is to add the query logic
that the SqlDataSource will use when it connects to the database. The complete declaration of the data
source control is:
bound control that uses the data from the data source control. In this case, a DropDownListcontrol is
used as the data-bound control:
Connection Strings from the Configuration File
In ASP.NET 2.0, Microsoft has tried to address the common shortcomings in the Web.config file with
ASP.NET 1.x. One such shortcoming is that there is not a well-defined location for storing connection
strings. Because database connection information is so frequently stored in the Web.configfile, you
now have an entirely new configuration section in that file,
ing the connection string information.
Although you can hard-code the connection string directly in the SqlDataSource tag (as shown in the
previous section), you should always place it in the
file to guarantee greater flexibility and ensure that you won’t inadvertently change the connection
string, which minimizes the effectiveness of connection pooling. For example, add the below connection
string in the Web.configfile:
...
SqlDataSource using the $ expression, as shown below:
DataSets in .NET
Procedure Example in Oracle
Procedure:
Also KNown As “Stored Procedures”
· Named block
· Can process several variables
· Returns no values
· Interacts with application program using
IN, OUT, or INOUT parameters are Valid parameters include all data types such as Integer,Char,Varchar2,date etc.
However, for char, varchar2, and number no length and scale, respectively, can be specified.
For example, the parameter number (6) results in a compile error and must be replaced by number
CREATE [OR REPLACE] PROCEDURE name
[( argument [IN|OUT|IN OUT] datatype
[{, argument [IN|OUT|IN OUT] datatype }] )]
AS
/* declaration section */
BEGIN
/* executable section - required*/
EXCEPTION
/* error handling statements */
END;
/
» IN (default) : means that the parameter can be referenced inside the procedure body, but it cannot be changed
» OUT: means that a value can be assigned to the parameter in the body, but the parameter’s value cannot be referenced.
The OUT qualifier signifies that the procedure passes a value back to the caller through this argument
» IN OUT: allows both assigning values to the parameter and referencing the parameter.
Executing procedures
» EXECUTE
» EXECUTE
A procedure can be deleted using the command:
drop procedure
Procedure Example
myProcedure(bookname in varchar2,quantity integer,price number) AS
BEGIN
INSERT INTO books Values(bookname,quantity,price);
END;
/
To Execute This Procedure Using this Command:
exec myProcedure('Teach Yourself C++',100,125);
Triggers in Oracle
A database trigger is procedural code that is automatically executed in response to certain events on a particular table or
view in a database. The trigger is mostly used for keeping the integrity of the information on the database. For example,
when a new record (representing a new Employee) is added to the Employee_Info table, new records should be created also in the
tables of the taxes, vacations, and salaries.
Before a trigger can be created, the user SYS must run a SQL script commonly called DBMSSTDX.SQL. The exact name and
location of this script depend on your operating system.
1.To create a trigger in your own schema on a table in your own schema or on your own schema (SCHEMA), you must have
the CREATE TRIGGER system privilege.
2.To create a trigger in any schema on a table in any schema, or on another user's schema (schema.SCHEMA), you must
have the CREATE ANY TRIGGER system privilege.
3.In addition to the preceding privileges, to create a trigger on DATABASE, you must have the ADMINISTER DATABASE
TRIGGER system privilege.
If the trigger issues SQL statements or calls procedures or functions, then the owner of the trigger must have the privileges necessary to perform these operations. These privileges must be granted directly to the owner rather than acquired through roles.
Examaple :
Create A Table On books where bookid,authorname,price,quantity,edition etc are stored .There are also another table where
sale information are stored.
bookname varchar2(20),
authorname varchar2(30),
quantity integer,
price number(10,2),
edition varchar2()
);
CREATE TABLE sales(
saleid integer,
bookname varchar2(20) FOREIGN KEY,
price number(10,2),
quantity integer
);
when a record insert into sales table then quantity of corresponding book in books table must be updated. we will do it
using trigger . This trigger run when a record insert into sales table.
CREATE OR REPLACE TRIGGER Book_TRIGGER
AFTER INSERT ON sales
FOR EACH ROW
DECLARE
BEGIN
UPDATE books SET quantity=quantity-:new.quantity where bookname=:new.bookname;
END;
/
if books table have a book named teach yourself C++ which quantity is 20. IF A teach yourself C++ book sells then teach yourself C++ book will
book's quantity will be 19 .we will do it using above Book_TRIGGER trigger.
Oracle Job Scheduler
Oracle Job Schedular
The DBMS_JOB package is actually an API into an Oracle subsystem known as the job queue . The Oracle job queue allows for
the scheduling and execution of PL/SQL routines (jobs) at predefined times and/or repeated job execution at regular intervals.
The DBMS_JOB package provides programs for submitting and executing jobs, changing job execution parameters, and removing or
temporarily suspending job execution. This package is the only interface with the Oracle job queue.
DBMS_JOB is used to schedule many different types of tasks that can be performed in PL/SQL and that require regular execution.
The job queue is used extensively by Oracle replication facilities, and was originally developed for the purpose of refreshing
Oracle snapshots. DBMS_JOB is often used by DBAs to schedule regular maintenance activities on databases, typically during
periods of low usage by end users. It can similarly be used by applications to schedule large batch operations during off
hours. The job queue can also be used to start up service programs that listen on database pipes and respond to service requests
by user sessions.
Example:
emp_name varchar2(20),
emp_dob date
);
CREATE TABLE message(
emp_name varchar2(20),
msg varchar2(50)
);
CREATE OR REPLACE PROCEDURE send_msg
CURSOR emp_cur IS select emp_name from employee_info ;
var date;
BEGIN
for variable in emp_cur
LOOP
select emp_dob into var from employee_info where empo_name=variable.name;
IF TO_CHAR(var,'dd-mm-yyyy')=TO_CHAR(emp_dob,'dd-mm-yyyy') THEN
INSERT INTO message VALUES(variable.emp_name,'Happy Birthday');
END IF;
END LOOP;
\\here job schedular example which call send_msg procedure to check birthday
BEGIN
DBMS_SCHEDULER.create_job (
job_name => 'test_full_job_definition',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN send_msg; END;',
start_date => SYSTIMESTAMP,
repeat_interval => 'freq=daily; byminute=0; bysecond=0;',
end_date => NULL,
enabled => TRUE,
comments => 'Job defined entirely by the CREATE JOB procedure.');
END;
/
Internet Information Server in .NET
Functions in Oracle
Function:
A function is a subprogram that returns a single value. You must declare and define a function before invoking it. You can
either declare and define it at the same time, or you can declare it first and then define it later in the same block.
The syntax for a function is:
[ (parameter [,parameter]) ]
RETURN return_datatype
IS | AS
[declaration_section]
BEGIN
executable_section
[EXCEPTION
exception_section]
END ;
/
Function Example
CREATE OR REPLACE FUNCTION
myFunction(booknam in varchar2)
RETURN INTEGER AS
quan INTEGER;
BEGIN
SELECT quantity into quan FROM books WHERE bookname=booknam;
RETURN quan;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN 0;
END;
select myFunction('Teach Yourself C++') from dual;
A few more differences between a procedure and a function:
1.A function MUST return a value
2.A procedure cannot return a value
3.Procedures and functions can both return data in OUT and IN OUT parameters
4.The return statement in a function returns control to the calling program and returns the results of the function
5.The return statement of a procedure returns control to the calling program and cannot return a value
6.Functions can be called from SQL, procedure cannot
7.Functions are considered expressions, procedure are not
Managed Provider Factories in .NET
Using Message Contracts
Future WCF developers will frequently define service and message contracts, but using mes-
sage contracts to explicitly define the message structure will likely be less common. This can
prove useful if you need to interoperate with another (non-WCF) service, which requires a
particular message format.
To define a message contract, you use the MessageContract, MessageHeader, and
MessageBody attributes as shown here:
sage contracts to explicitly define the message structure will likely be less common. This can
prove useful if you need to interoperate with another (non-WCF) service, which requires a
particular message format.
To define a message contract, you use the MessageContract, MessageHeader, and
MessageBody attributes as shown here:
Using Data Contracts in WCF
Using Data Contracts
Data contracts describe the structure of data passed in and out of the service. In the case of
simple, known types such as integers and strings, WCF applies a default contract; if your serv-
ice exposes only simple types, you do not need to define a data contract. The CustomerService
contract shown in the previous listing, however, exposes a CustomerDatatype, which is a com-
plex type and, therefore, requires a data contract.
Again, WCF makes it easy to define a data contract by providing several attributes that you
can use to decorate the CustomerDatatype:
using System.Runtime.Serialization;
[DataContract]
public class CustomerData
{
[DataMember]public string FirstName;
[DataMember]public string LastName;
[DataMember]public string Email;
}
such as XmlElementand XmlAttribute. However, unlike today’s Web Services, WCF does not by
default use the XmlSerializer to serialize complex types. Instead it uses XmlFormatter, which
has better support for versioning and understands these new DataContractand DataMember
attributes. You can explicitly specify the desired formatter using the FormatModeparameter of
the ServiceContract attribute as we show in the following example.
[ServiceContract(Namespace="http://indigorocks/", Name="CustomerService",
FormatMode = ContractFormatMode.XmlFormatter)]
interface ICustomerService
{ ... }
Revisiting WCF Contracts in ASP
Revisiting WCF Contracts
The concept of a contract is a core foundation to WCF. Address and binding are also important
pieces, but they track closer to an administrator’s set of responsibilities. Contracts, on the
other hand, are firmly rooted in the developer’s space.
WCF defines three different types of contracts:
• Service contract : As we mentioned earlier, this defines the service operations and the
input and output parameters of each operation. Every service must have one associated
service contract and may have more.
• Data contract: This defines the data structure WCF uses to serialize and deserialize an
instance of a complex type. Data contracts must be associated with every complex type
exposed by a service operation as parameters or return values.
• Message contract: This enables you to explicitly define the layout of a message; for
example, what goes in the header versus what goes in the body of the message.
The following sections provide some more details about each of the contract types.
Using Service Contracts
WCF provides three attribute types that together allow you to define a service contract:
ServiceContract, OperationContract, and BindingRequirements.
You’ve already seen simple examples of ServiceContract and OperationContract. Under-
stand that each of these provides additional parameters that allow you to further refine the
contract. For example, consider this service contract, which shows some ServiceContract and
[ServiceContract(Namespace="http://indigorocks/", Name="CustomerService")]
interface ICustomerService
{
[OperationContract()]
CustomerData GetCustomerByEmail(string email);
[OperationContract(IsOneWay=true)]
void SaveCustomer(CustomerData cust);
}
Namespace and Nametogether enable you to explicitly specify the namespace and name of
the contract. By default, WCF uses the full interface or class name. Also notice the IsOneWay
parameter is set in the OperationContract to indicate that the SaveCustomermethod is a one-
way operation with no return values.
Calling the WCF Service in ASP
Calling the Service
WCF supports several ways to create and configure a client to call a service. First, as was the
case with hosting a service, the calling code can exist within any type of application—web
application, Windows application, even another WCF service.
Regardless of the client application type you choose, the client requires several bits of
information to successfully call the service.
• The service contract : This can be any local type (class or interface) that adheres to the
contract published by the service endpoint.
• The service address: This should be the same address configured in the service end-
point.
• The service binding: The client must use the same protocols, transport, and encoding as
the service endpoint.
Notice that these three pieces of information match the information exposed by the service
endpoint exactly. In fact, the client must use this information to establish a client-side end-
point. Similar to the service endpoint, the client-side endpoint establishes the communi-
cation plumbing going up to the service and also manages the message exchange.
WCF does not care exactly how all this information gets to the client. You could, for exam-
ple, manually code the contract type into the client and set the proper address and binding in
the configuration file. Here’s what this might look like:
// This must adhere to the service contract, but does NOT need
// to be named the same.
[ServiceContract]
interface INotTheSameNameAsService
{
[OperationContract]
int Add(int n1, int n2);
[OperationContract]
int Subtract(int n1, int n2);
}
Hosting the WCF Service in ASP
Hosting the Service
A WCF service can be hosted in many types of applications: Windows Service, Windows Forms,
ASP.NET, and even a simple console application. Although ASP.NET will likely be the most
popular host for services, for the sake of simplicity the following example demonstrates how
to host a service within a simple console application.
static void Main(string[] args)
{
using (ServiceHost
new ServiceHost
{
// communication infrastructure set up on call to open
service.Open();
//Stay alive to process requests
Console.WriteLine("Hit [Enter] to exit");
Console.ReadLine();
}
}
The points of interest in this simple example are the ServiceHost constructor call and the call
to Service.Openmethod. By constructing the generic ServiceHost class with the MathService
parameter, the runtime generates a hosting environment for the MathService service. The
ServicedHost.Open method establishes the communication infrastructure required by each
endpoint based on its binding. Each opened ServicedHostconsumes its share of resources,
so it’s important to close the service to release those resources. You could do this explicitly
by calling the Close method on the ServiceHost, but the previous example implements
a using block that implicitly closes the ServiceHost once the thread leaves the scope of the
using block.
Specifying the Address and Binding of WCF in ASP
Specifying the Address and Binding
In addition to implementing a contract, each endpoint also contains an address and a binding.
The address is essentially a URL that defines the location of the endpoint (and the service by
extension) in the network.
Bindings are a little more interesting. The endpoint binding defines what protocols, trans-
port, and encoding the endpoint will use for all its communication. You can create a custom
binding, but WCF provides several useful built-in bindings. Table 9-2 shows a partial list of these.
Although you can configure the address and binding programmatically, it’s much easier (not
to mention more flexible) to configure these in the app.configfile (or web.configfile) as we
show here:
As you can see, the
address, binding, and contract type.
Remember, by definition a service can contain multiple endpoints. Here’s the configura-
tion for this scenario, where multiple endpoints are applied to one service:
Programming with WCF
The ABCs of WCF: Address, Binding, and Contract
Concisely stated, a WCF service is a collection of endpoints where each endpoint implements
a service contract and contains a binding and an address. Crystal clear, right? Probably not, so
in this section, we elaborate on this definition by illustrating what is meant by contracts, bind-
ings, and addresses.
Defining Service Contracts
Defying convention, a good place to start is with the C, which actually represents service con-
tract. A service contract defines the service operations and the input and output parameters
of each operation. In fact, this notion is extremely similar to the
today. A service contract is typically defined by applying attributes to a class or interface:
[ServiceContract]
class MathService
{
[OperationContract]
public int Add(int n1, int n2)
{
return n1 + n2;
}
[OperationContract]
private int Subtract(int n1, int n2)
{
return n1 - n2;
}
}
utes combine to create the service contract. The OperationContract attributes are analogous
to the familiar WebMethod attribute in that each attribute defines the attached method as an
exposed operation. However, notice that the Subtractmethod is private. In WCF, the access
modifiers are orthogonal to the service contract and, therefore, have no bearing on what can
or cannot be exposed outside the service.
These attributes can also be applied to an interface to create the service contract. For
example:
[ServiceContract]
interface IMathService
{
[OperationContract]
int Add(int n1, int n2);
[OperationContract]
int Subtract(int n1, int n2);
}
class MathService : IMathService
{
public int Add(int n1, int n2)
{
return n1 + n2;
}
public int Subtract(int n1, int n2)
{
return n1 - n2;
}
}
to implement the IMathService interface. Since it’s desirable to keep the contract separate from
the implementation, using an interface to define the service contract is the preferred approach.
YASOE: Yet Another Service Orientation Explanation in ASP
The terms service orientation (SO) and Service Oriented Architecture (SOA) are clearly the
new buzzwords leading us into the next generation of distributed applications and shaping
the stack of technologies that enable developers to implement them.
Despite (or maybe because of ) the huge amount of cyberspace real estate dedicated to
SO/A explanations, debates, and marketing, the SO/A semantics still remain unclear. Line up
ten SO/A enthusiasts and ask each “What is SO/A?” and you’ll get ten different answers, each
with varying degrees of overlap and conflict. These discussions, frankly, are becoming more
and more tedious and at the same time less and less fruitful.
That said, we still feel compelled to convey our SO/A point of view within this chapter.
Not because we believe ours is the canonical one, but because:
• Not everyone has had the luxury of reading the hundreds of SO/A related articles,
slides, and presentations. For these folks, this section serves as a nice overview of the
concepts.
• Those who are already veterans of the SO/A definition wars may benefit from this sec-
tion because it explains what we mean when we refer to SO/A. Hopefully, this will ward
off confusion (not to mention a few angry e-mails) based purely on semantics.
SO/A: Revolution, Evolution, or Neither?
One of the many complaints we often hear regarding SO/A is that it offers nothing that sophis-
ticated and successful distributed implementations aren’t already doing. To which we simply
say: “That’s the point.” We’ve all learned many hard lessons over the past few years by watch-
ing distributed applications deliver disappointing results or completely fail. The primary goal of SO/A is to take those lessons to heart and document the characteristics of the most success-
ful distributed systems. The hope is that this information will help future developers avoid the
same mistakes that crippled many early attempts at building distributed applications.
Therefore, we see SO/A as a meta-pattern. Like any pattern, it defines a proven approach
that incorporates the experience of architects and developers as they struggled to build these
systems. Or, as Joe Long of Microsoft succinctly said: “Service orientation is all about building
distributed systems the right way.”
Objects vs. Services: The Metaphor Matters
If you compare object orientation with service orientation, the first obvious distinction is the
use of the object metaphor versus the service metaphor. The object metaphor is simply an
abstraction to help humans better understand the machine code underneath. This, in turn,
makes it easier for humans to reason about and organize the larger system.
By nature, a metaphor implies characteristics. An object, for example, has attributes and
behaviors, and maintains its own state. In the context of software development, an object
implies chatty interfaces and support for encapsulation, inheritance, and polymorphism.
Objects and their implied characteristics have proved extremely helpful when you’re design-
ing and implementing local systems. However, in the early ’90s, high-speed LAN networks
became more common, making it feasible to create applications that were distributed across
several physical machines. Later, the emergence of the Web made it possible to communicate
with business partners over this common networking infrastructure rather than using a costly
propriety infrastructure.
Given the success of objects in the local context, it seemed natural to also apply the object
metaphor in the distributed context. Unfortunately, the characteristics that worked so well in
the local context were ineffective and even destructive in the distributed context. Specifically,
chatty interfaces caused an object-based distributed solution to perform poorly and stateful
objects made it extremely difficult to scale the system out. When you think about it, that’s a
fatal combination. Over time, many developers learned these issues and began developing
“objects” that were stateless and exposed chunky interfaces. But, of course, the resulting entity
was not an object at all. The bottom line is that the object metaphor actually hindered, rather
than helped, developers in gaining an understanding of the best way to develop a distributed
system.
Unlike past distributed approaches, which tried to take the round object metaphor and fit
it into the square distributed world, SO/A introduces a new metaphor—the service, whose
characteristics are much better aligned with the realities of the distributed world. The service
metaphor helps humans reason about the communication that occurs between two distrib-
uted applications. It also implies the characteristics that help make that communication as
efficient, flexible, and open as possible.
Understanding the WCF Motivations
Understanding the WCF Motivations
As with any new technology, having a good understanding of WCF begins with having an
appreciation for its underlying motivations. After all, .NET currently has several effective tech-
nologies that enable you to build distributed applications: .NET Remoting, MSMQ, Enterprise
Services, and, of course, Web Services. What is the point of having yet another distributed
technology? In this section, we tackle this all-important question.
Problem: Distributed Technology Soup
In the previous paragraph, we mentioned the many distributed technologies that are already
available to .NET developers. To save syllables and trees, we’ll collectively refer to these four
technologies—.NET Remoting, MSMQ, Enterprise Services, and Web Services—as the “Big
Four.”
1
Although it’s usually nice to have many options, in this case, the number of options
combined with large amounts of overlapping functionality make it extremely difficult to
choose the right technology for the job. Of course, each of the Big Four exhibits distinct advan-
tages and disadvantages relative to the others. But deciding the right technology based on
them may require application and infrastructure knowledge that you may not yet have. For
example, you may choose Web Services to leverage its loose coupling advantage, only to find
out much later that the actual application load requires the performance advantage of Enter-
prise Services. Given that the programming models for each of the Big Four differ greatly,
switching to another technology midstream in the development cycle proves difficult and
costly.
To better understand the nature of the problem, take a look at Table 9-1. This table details
each technology’s characteristics, advantages, and disadvantages. Looking at this, it’s no won-
der that news groups and forums are flush with which, when, where, and why questions
regarding the Big Four.
WCF’s Solution to Distributed Technology Soup
WCF solves the distributed technology soup problem by incorporating the best of each Big
Four technology into one programming model. For developers, this eases the burden of hav-
ing to remember four extremely different models. It also simplifies the task of switching
midstream to another distributed technique.
In terms of a programming model, WCF actually supports three levels of “programming”:
API, declarative attributes, and configuration. The extensive WCF API exposes all of its func-
tionality including low-level plumbing and extensibility points. Although the API is powerful,
WCF also defines many attributes that are much simpler to use and that support most scenar-
ios. Finally, WCF’s configuration support enables you modify many settings without even
touching your source code.
Beyond providing a simple programming mode, WCF’s attribute-based approach also
enables you to expose a component on the wire without deriving from a special base class. In
contrast, .NET Remoting and Enterprise Services require that you derive your remote object
from MarshalByRefObjectand ServicedComponent, respectively. Because .NET allows only one
base class, this makes it difficult to incorporate your own custom base class.
Client Script Manager in ASP
Version 1.x of the Framework has a handful of methods hanging off of the Pageobject to help
with client-side scripting. One of these, for example, is RegisterClientScriptBlock. This
handy method accepts two strings. The first one names the script block; the second is the
actual script you want to inject into the page.
You use this from controls to inject script into the page while avoiding duplicate script
blocks. If more than one instance of a control attempts to inject the same script block, the
runtime is smart enough to inject it only once. From the previous example, you could pull the
populateListB method out into a file named Interdepends.js. From the implementation of
the interdependent lists control, you could add a line of code to include it:
this.RegisterClientScriptBlock(
"Interdepends",
"scripts");
This is a two-fold improvement over the previous example. It gets the script out into its
own file (for easier maintenance and versioning), and it guarantees that the block will be
included in the page only once.
All of the RegisterXYZ methods (see Table 4-2) have been deprecated in version 2.0 of the
Framework. Instead, the page object now carries an instance of the new ClientScriptManager
type, named ClientScript. This centralizes the functionality for managing scripts; you no
longer have a handful of random methods hanging off the page object.
Of course, you must realize that 2.0 attempts to be backwards compatible, so just because
these are deprecated doesn’t mean they go away. They will survive in-perpetuity in the name
of backwards compatibility (or until Microsoft ships a non-backwards compatible version of
ASP.NET), so your existing code will continue to work.
With new development, however, you should use the methods of the client script man-
ager. Let’s take a look at these. The point of a lot of these register methods is first and foremost
to avoid duplicating the code that’s being sent to your page, which can happen easily when a
control is generating code and more than one instance of the control is placed on a single Web
Form. Some of these methods also do a bit of code generation for you, but it’s nothing sub-
stantial.
Creating an Http Handler in ASP
It’s possible to create a type that implements the IHttpHandlerinterface and have it respond
to any pattern of URL. The advantage is you have full control over the URL, and the URL of the
request doesn’t need to correspond to a physical file. The downside is that IIS configuration is
required to map the URL into the framework, and ASP.NET configuration is required to map
the URL to your specific handler.
The alternative is to use the built-in, simple handler factory. This handler is mapped to
files with an ASHX extension. The WebHandlerdirective is used to point an ASHX page at a type
that implements the IHttpHandlerinterface. Visual Studio adds a file with this directive to
your project via the Generic Handler option in the Add New Item dialog window.
using System;
using System.Web;
using System.Web.Caching;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
public class MyHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
byte[] b;
object id = context.Request.QueryString["BookId"];
b = (byte[])context.Cache[string.Format("Book{0}",id)];
if (b == null)
{
SqlConnection cn = new SqlConnection(ConfigurationManager.
ConnectionStrings["Library_local"].ConnectionString);
string sql = "select CoverImage from BookCoverImage";
sql += " where bookid = @BookID";
SqlCommand cm = new SqlCommand(sql, cn);
cm.Parameters.Add("@BookId", SqlDbType.Int).Value = id;
cn.Open();
SqlDataReader dr = cm.ExecuteReader();
if (!dr.Read())
context.Response.End();
b = (byte[])dr[0];
context.Cache.Insert(string.Format("Book{0}", id),
b,
null,
DateTime.Now.AddSeconds(60),
Cache.NoSlidingExpiration);
dr.Close();
cn.Close();
}
context.Response.OutputStream.Write(b, 0, b.Length - 1);
}
public bool IsReusable {
get { return true; }
}
}
An Asynchronous Messaging Architecture ASP
MSMQ and COM+ Queued Components are used to accomplish this. Clustering was not an
option considering the budget on this example project, and so to provide for “availability” of
the data access layer, MSMQ and database triggers are leveraged to programmatically syn-
chronize the data in these redundant servers.
This architecture is based entirely on XML. All of the controls in the user interface repre-
sent their state as XML documents, and it’s XML that gets packed into the body of the MSMQ
messages.
Users of this application don’t have a very fast connection, so page sizes are kept to a min-
imum. This means page developers will likely favor caching data on the web server to rebind a
control like a grid across postbacks, rather than rely on ViewState to maintain this information
on the client (see Chapter 4).
The data access layer on the web server needs to support asynchronous operations.
Commands that modify the data are sent to the data access abstraction layer, which doesn’t
actually execute the command, but packs the XML representing the request into the body
of an MSMQ message. This message is then placed in a queue, and execution continues in the call stack on the web server. This means that the web server responses don’t wait for the database work to be done before sending a result to the user. Users see a message that their
requests were sent and to check back later for results. See Chapter 8 for MSMQ examples.
Of course, sometimes synchronous access to the database is critical. When users want to
see data, you cannot tell them that a request for the data they want to see has been submitted,
and to come back later to see it. For synchronous requests for data, you use a simple timeout
listener loop within the data access abstraction layer. This monitors an incoming MSMQ for a correlated result message, sent back from the queue listener when the work has been
completed. This architecture makes it very easy to put in a timeout should the request take
too long. This timeout period can (and should) be controlled by a configuration file. With a
10-second timeout specified in the configuration file, users get an error or warning message
if they wait any longer for a message to appear in the response queue.
A Widely Distributed Service Application ASP
tion deploys a data access layer to the IIS box running Web Services, and uses ASP.NET session
state to manage logins and state information (see Figure 1-6). This service layer is then
leveraged by Windows Forms and Web applications distributed across several North American
locations. Web Service extensions are leveraged to encrypt authentication and sensitive data
on the wire.
The data access layer leverages the Data Access Application Block, which is part of a
downloadable package called Enterprise Services. This set of services ships with all the source
code, and so can be customized. The Data Access Application Block ships with support for
SQL Server, Oracle, and DB2. DB2 requires the managed provider available from IBM. There is
also a stateful business object layer used within the Windows Forms user interfaces and dur-
ing the processing of a request for an ASP.NET page. It’s good to use stateful objects within a
process boundary; you need stateless objects when services could possibly be deployed to
different machines, processes, or even app domains.
Web Services are designed as a stateless service layer. This is considered to belong to the
middle tier of a distributed application, but has a very different design than a typical stateful
type designed with the principles described by OOAD.
The funny thing about SOAP, the “Simple Object Access Protocol,” is that it is not at all object oriented. Services designed to be exposed using SOAP messages actually look a lot more like traditional procedure function calls might: atomic methods that accept large
parameter lists that perform their work based entirely upon the information passed to them,
and when finished, are destroyed completely (see Figure 1-7, the class on the right).
Running Codes
Using Serviced Components in ASP
Component Services, or COM+, provides a rich set of features in a component-hosting envi-
ronment, such as distributed transactions, just-in-time activation, object pooling, and
asynchronously queued components. In Chapter 7, we examine these features in detail.
Even though Component Services is a COM-based technology, Microsoft has added facili-
ties to the .NET Framework that allow managed types to be easily configured for use within
this environment. When you create .NET types that can be hosted under Component Services,
they are called Serviced Components.
Here’s a logical view of an architecture that uses Serviced Components (see Figure 1-3).
The critical feature of Component Services being leveraged from this architecture is its
ability to automatically roll back transactions that span several data sources. Even if the data
isn’t hosted on the same server or on the same vendor platform, the Distributed Transaction
Coordinator will automatically manage and then commit or roll back work that spans differ-
ent data stores.Since it’s a web-based application, it’s possible to deploy all of the logical tiers of this
system to a single physical tier. Here’s a physical view of the deployment of this system into
production (see Figure 1-4).
Deployment to a single physical tier means that all layers of the application execute in-
process with one another. This is a great boon to performance. An extra hop across a process
boundary, or especially a hop across machine boundaries, can make an application perform
many times slower than when all components are created in-process.
The other thing to notice about this application is that sticky sessions are in use at the
load balancer layer in order to support the use of in-process sessions. The session data is left
in-process for the performance benefit gained by avoiding the extra network hop to retrieve
and retain the state information.
Running Codes
One of the trade-offs of this approach is the decreased efficiency of the load balancing
algorithm. However, the load of this site is easily handled by the two web servers, and there
could be a third in the mix, for failover support, should one of the servers crash. So under
normal operations, with three servers handling the traffic, they don’t even break a sweat. The
loss in efficiency of the load balancing algorithm doesn’t sacrifice acceptable application
performance.
A Simple Managed Application in ASP
A Simple Managed Application
Here is a typical simple architecture for a smaller application with a single data store that’s n
expecting hundreds of concurrent users (see Figure 1-2). All of the components are managed
types. The ASP.NET pages use standard controls built into the Framework that generate
W3C-compliant HTML. This allows the application to be deployed to any platform or
operating system that supports a web browser. The pages use what could be a stateful busi-
ness object layer, but the application is simple enough that only a few of these stateful types
are actually needed. The business object layer, in turn, leverages a data access layer written
using the Data Access Application Block and calling SQL Server stored procedures.
In some cases, the UI layer calls the data access layer directly. Although this is a violation
of the guidance provided by the layering pattern, in this case, it’s acceptable as the business
rules aren’t that complex and, in many cases, would be nothing more than a “pass-thru” layer,
providing nothing but an additional level to the call stack and bloating your code base, assembly sizes, and heap allocations unnecessarily.
Even with this simple design, this application could scale out to handle additional load in
the future. The requirements for what needs to be managed in state are minimal enough that
they’re easily implemented using cookies (good only for small amounts of data), and the data-
base (more coding, but it’s persistent, scalable, and available).
Access to the database is synchronous, so any long-running queries would incur a delay
in the responsiveness of the application for the user, as there’s nothing in this design to
address asynchronous operations. The recovery plan, should the server go down, is to drive to
the office as fast as possible and repair or replace the machine. This results in a low availability
guarantee, which is acceptable because the application isn’t mission critical. Any requests
in-process during a system crash would be lost.
Deployment of new versions and fixes for this application are worry free. State informa-
tion is tracked in the database, and correlated to users with a cookie value. Both of these stores
survive the reboot of a web server.
This architecture would obviously not work for all applications. There are a number of
serious limitations. However, when the requirements are met by this solution, it’s an excellent
choice, because developing applications like these are extremely fast and very easy to learn,
compared to a lot of n-tiered applications.




