Creating Custom HTTP Modules An HTTP Module is a .NET class that executes with each and every page request.. You can use an HTTP Module to handle any of the HttpApplication events that y
Trang 1private string _conString;
private SqlConnection _con;
private SqlCommand _cmdSelect;
private SqlCommand _cmdInsert;
public override void Init()
{
// initialize connection
_conString =
➥WebConfigurationManager.ConnectionStrings[“Log”].ConnectionString;
_con = new SqlConnection(_conString);
// initialize select command
_cmdSelect = new SqlCommand(“SELECT COUNT(*) FROM Log WHERE Path=@Path”,
➥_con);
_cmdSelect.Parameters.Add(“@Path”, SqlDbType.NVarChar, 500);
// initialize insert command
_cmdInsert = new SqlCommand(“INSERT Log (Path) VALUES (@Path)”, _con);
_cmdInsert.Parameters.Add(“@Path”, SqlDbType.NVarChar, 500);
}
public int NumberOfRequests
{
get
{
int result = 0;
_cmdSelect.Parameters[“@Path”].Value =
Request.AppRelativeCurrentExecutionFilePath;
try
{
_con.Open();
result = (int)_cmdSelect.ExecuteScalar();
}
finally
{
_con.Close();
}
return result;
}
}
void Application_BeginRequest(object sender, EventArgs e)
{
// Record new request
Trang 2_cmdInsert.Parameters[“@Path”].Value =
Request.AppRelativeCurrentExecutionFilePath;
try
{
_con.Open();
_cmdInsert.ExecuteNonQuery();
}
finally
{
_con.Close();
}
}
</script>
The Global.asax page in Listing 31.22 handles the Application BeginRequest() event
You can handle any application event by following the naming pattern
Application_EventNamewhere EventNameis the name of the HttpApplication event.
In Listing 31.22, the Application_BeginRequest() handler records the path of the page
requested A SqlCommand object records the page path to a database table named Log The
Global.asax file also extends the base HttpApplication class with a custom property
named NumberOfRequests This property retrieves the number of requests made for the
page at the current path
Finally, the Global.asax includes an Init() method that overrides the base
HttpApplication’s Init() method In Listing 31.22, the Init() method initializes the
SqlConnection and two SqlCommand objects used in the Global.asax file The Init()
method is called when the class represented by the Global.asax is initialized It is called
only once, when the class is first created
WARNING
The same instance of the HttpApplication object is reused for multiple page requests
(although never for multiple page requests at the same time) Any value that you assign
to a property in a Global.asax file is maintained over the multiple page requests
The page in Listing 31.23 displays the value of the custom property exposed by the
Global.asax file (see Figure 31.7) The ApplicationInstance property is used to refer to
the instance of the HttpApplication class associated with the page Because the
Global.asax file is compiled dynamically in the background, any properties that you
declare in the Global.asax file are exposed as strongly typed properties
Trang 3FIGURE 31.7 Displaying the NumberOfRequests property
LISTING 31.23 ShowGlobal.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show Global</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
This page has been requested
<%= this.ApplicationInstance.NumberOfRequests %>
times!
</div>
</form>
</body>
</html>
Trang 4Creating Custom HTTP Modules
An HTTP Module is a NET class that executes with each and every page request You can
use an HTTP Module to handle any of the HttpApplication events that you can handle in
the Global.asax file
Behind the scenes, ASP.NET Framework uses HTTP Modules to implement many of the
standard features of the framework For example, ASP.NET Framework uses the
FormsAuthenticationModule to implement Forms authentication and the
WindowsAuthenticationModule to implement Windows authentication
Session state is implemented with an HTTP Module named the SessionStateModule Page
output caching is implemented with an HTTP Module named the OutputCacheModule, and
the Profile object is implemented with an HTTP Module named the ProfileModule
When a new instance of an HttpApplication class is created, the HttpApplication loads
all the HTTP Modules configured in the web configuration file Each HTTP Module
subscribes to one or more HttpApplication events For example, when the
HttpApplication object raises its AuthenticateRequest event, the
FormsAuthenticationModule executes its code to authenticate the current user
In this section, we create a simple authentication HTTP Module The HTTP Module
doesn’t enable you to request a page unless you include the proper query string with the
request The code for the custom HTTP Module is contained in Listing 31.24
LISTING 31.24 App_Code\QueryStringAuthenticationModule.cs
using System;
using System.Web;
namespace AspNetUnleashed
{
public class QueryStringAuthenticationModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.AuthorizeRequest += new EventHandler(AuthorizeRequest);
}
private void AuthorizeRequest(Object sender, EventArgs e)
{
// Get context
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
// If the request is for Login.aspx, exit
Trang 5string path = context.Request.AppRelativeCurrentExecutionFilePath;
if (String.Compare(path, “~/login.aspx”, true) == 0)
return;
// Check for password
bool authenticated = false;
if (context.Request.QueryString[“password”] != null)
{
if (context.Request.QueryString[“password”] == “secret”) authenticated = true;
}
// If not authenticated, redirect to login.aspx
if (!authenticated)
context.Response.Redirect(“~/Login.aspx”);
}
public void Dispose() { }
}
}
The class in Listing 31.24 implements the IHttpModule interface This interface includes
two methods:
Init—Enables you to subscribe to HttpApplication events
Dispose—Enables you to clean up any resources used by the HTTP Module
In Listing 31.25, the Init() method adds an event handler for the HttpApplication
AuthorizeRequest event When the HttpApplication raises the AuthorizeRequest event,
the HTTP Module’s AuthorizeRequest() method executes
The AuthorizeRequest() method checks for a password=secret query string If the query
string does not exist, the user is redirected to the Login.aspx page (The method also
checks whether the user is requesting the Login.aspx page to avoid a vicious circle.)
Before you can use the QueryStringAuthenticationModule, you must register the HTTP
Module in the web configuration file The web configuration file in Listing 31.25
includes an <httpModules> section that registers the module
LISTING 31.25 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<httpModules>
Trang 6<add name=”QueryStringAuthenticationModule”
type=”AspNetUnleashed.QueryStringAuthenticationModule”/>
</httpModules>
</system.web>
</configuration>
After you register the HTTP Module, if you attempt to request any page without including
the password=secret query string, you are redirected to the Login.aspx page (If the
Login.aspx page doesn’t exist, you receive a 404 Not Found error message.)
Summary
In this chapter, you learned how to extend the ASP.NET Framework by extending different
parts of the HTTP Runtime In the first section, you learned how to create a custom
BuildProvider For example, you learned how to create a BuildProvider that dynamically
generates a data access component from an XML file
Next, you explored the topic of ExpressionBuilders You learned how to use an
ExpressionBuilder to automatically replace one expression with another For example, we
created a custom ExpressionBuilder that enables you to look up a value from an XML file
The topic of HTTP Handlers was also explored You learned two methods of creating
custom HTTP Handlers You learned how to create a Generic Handler and how to create
an HTTP Handler by implementing the IHttpHandler interface You also saw how you can
improve the scalability of your ASP.NET applications by implementing asynchronous
HTTP Handlers
Finally, you learned two methods of handling application-wide events You learned how
to create a custom HttpApplication by creating a Global.asax file You also learned how
to handle application events by implementing a custom HTTP Module
Trang 7ptg
Trang 8Building Dynamic Data
Applications
Introducing ASP.NET Dynamic Data
Building a Dynamic Data Application
Working with Dynamic Data Templates
Summary
ASP.NET Dynamic Data originally appeared in NET
Framework 3.5 Service Pack 1 release and its templates came
with Visual Studio 2008 SP1 This chapter provides you
with an overview of ASP.NET Dynamic Data and walks you
through the process of building an application with it and
discuss when you might (and might not) build a dynamic
data application
When you finish this chapter you should have a good idea
of what it’s like to build dynamic data applications and the
productivity benefits they provide for developers, and you
can compare and contrast this framework with traditional
Web Forms and ASP.NET MVC Framework
Introducing ASP.NET Dynamic Data
The hallmark of every good programmer is the ability to
locate redundant code and factor it out into a reusable
module or library Many people these days equate good
programming skills with writing far less lines of code than
we used to while still producing incredible applications
When we build ASP.NET applications that sit on top of a
data store of some kind, there are always a set of common
tasks that we need to provide a UI for Although the data
models can vary from application to application, several
common patterns emerge in virtually any data-driven
appli-cation Just a few of these patterns are listed here:
Entity Lists—Display a list of rows in a table.
Detail Form—Displays the details of a single entity.
Trang 9Edit Form—Enables the user to edit the details of a single entity.
Create—Adds a new entity to a list.
Delete—Deletes an entity from a list.
Navigation—Provides Search, Filter, Sort, and Paginate lists of entities.
These tasks are common to virtually all web applications regardless of the underlying data
model The ASP.NET Dynamic Data framework takes this into account and, out-of-the-box,
gives you scaffolding and templates that can provide all this functionality for you without
you writing more than a few lines of code In the next section, you see how to build a
dynamic data application, and you see the features and functionality provided for you as a
starting point
Building a Dynamic Data Application
Before we start building a sample application, we need something to build In the spirit of
keeping things simple so that we can focus this chapter solely on dynamic data, the
appli-cation must also be simple
We call it ZombiePedia, a website for cataloguing the appearances of various zombies
This way, during the zombie apocalypse, we can all hit ZombiePedia from our smart
phones to log zombies we’ve seen and look up repeat zombies to find their vital statistics
After all, we need to know if we can touch a zombie with bare hands or if it’s a virus
carrier, don’t we?
Without dynamic data, we would have to hand-code the page that displays the list of
zombie sightings, the sighting detail and edit forms, the ability to create new sightings,
and the pages that add, remove, and edit zombie types, and a bunch more plumbing
Doing this by hand, even with a rapid development framework like the MVC Framework,
would be tedious and time-consuming If our goal is to produce a functioning prototype
that we can use as the launching point to start building our production application, we
should use dynamic data
To start, let’s create a new web application Open up Visual Studio 2010 and create a new
project Under the Installed Templates panel in the Web category, click ASP.NET Dynamic
Data Entities Web Application (shown in Figure 32.1) Call the application whatever you
like, but ZombiePedia might be a good choice
This particular template creates an ASP.NET Dynamic Data website that comes
pre-equipped with code, scaffolding, and references to build a dynamic user interface on top
of ADO.NET Entity Framework Entity Data Model (EDM)
Before we go any further, we need to add the entity data model to our project You can
mock this up quickly by creating two simple tables in a SQL database: ZombieType (ID,
Name, Description) and ZombieSighting (ID, Name, Longitude, Latitude, and so on) Figure
32.2 shows the dialog box with which you are presented after right-clicking the project
Trang 10With a dynamic data website created and an entity data model added to the project, we’re
almost ready to run the application—no code written yet! First, let’s take a look at the
project that Visual Studio 2010 created for us
FIGURE 32.2 Adding an ADO.NET Entity Data Model by Generating from Database
FIGURE 32.1 Creating a new ASP.NET Dynamic Data Entries Project