Tải bản đầy đủ (.pdf) (10 trang)

Professional ASP.NET 3.5 in C# and Visual Basic Part 132 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (273.42 KB, 10 trang )

Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1271
Chapter 26: User and Server Controls
DesignerActionTextItem
is added to the collection (see Figure 26-18). The
DesignerActionTextItem
class allows you to add text menu items to the smart tag.
Figure 26-18
As shown in Figure 26-18, when you add the control to a Web page, the control now has a smart tag with
the
DesignerActionTextItem
class as content.
UI Type Editors
A UI type editor is a way to provide users of your controls with a custom interface for editing properties
directly from the Property Browser. One type of UI type editor you might already be familiar with is the
Color Picker you see when you want to change the
ForeColor
attribute that exists on most ASP.NET con-
trols. ASP.NET provides a wide variety of in-box UI type editors that make it easy to edit more complex
property types. The easiest way to find what UI type editors are available in the .NET Framework is to
search for types derived from the
UITypeEditor
class in the MSDN Library help.
After you find the type editor you want to use on your control property, you simply apply the UI Type
Editor to the property using the
Editor
attribute. Listing 26-45 shows how to do this.
1271
Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1272
Chapter 26: User and Server Controls
Figure 26-19
Listing 26-45: Adding a UI type editor to a control property


VB
<Bindable(True), Category("Appearance"), DefaultValue(""), _
Editor( _
GetType(System.Web.UI.Design.UrlEditor), _
GetType(System.Drawing.Design.UITypeEditor))
>
_
Public Property Url() As String
Get
Return _url
End Get
Set(ByVal value As String)
_url = value
End Set
End Property
C#
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Editor(typeof(System.Web.UI.Design.UrlEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public string Url
{
get
{
return url;
}
1272
Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1273
Chapter 26: User and Server Controls

set
{
url = value;
}
}
In this sample, you have created a
Url
property for a control. Because you know this property will be a
URL, you want to give the control user a positive design-time experience. You can use the UrlEditor type
editor to make it easier for users to select a URL. Figure 26-19 shows the Url Editor that appears when
the user edits the control property.
Summary
In this chapter, you learned a number of ways you can create reusable, encapsulated chunks of code.
You first looked at user controls, the simplest form of control creation. You learned how to create user
controls and how you can make them interact with their host Web pages. Creating user controls is quite
easy, but they lack the portability of other control-creation options.
Then, you saw how you can create your own custom server controls. You looked at many of the tools
you can create by writing custom server controls. These range from tools for emitting HTML and creating
CSS styles and JavaScript to those applying themes. The chapter also discussed the type of server controls
you can create, ranging from server controls that simply inherit from the
WebControl
class to templated
controls that give users of the control the power to define the display of the server control.
Finally, you looked at ways you can give the users of your server control a great design-time experience
by providing them with TypeConvertors, design surface interactions, and custom property editors in
your server control.
1273
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1275
Modules and Handlers
Sometimes, just creating dynamic Web pages with the latest languages and databases does not give

you, the developer, enough control over an application. At times, you need to be able to dig deeper
and create applications that can interact with the Web server itself. You want to be able to interact
with the low-level processes, such as how the Web server processes incoming and outgoing HTTP
requests.
Before ASP.NET, to get this level of control using IIS, you were forced to create ISAPI extensions
or filters. This proved to be quite a daunting and painful task for many developers because creat-
ing ISAPI extensions and filters required knowledge of C/C++ and knowledge of how to create
native Win32 DLLs. Thankfully, in the .NET world, creating these types of low-level applications
is really no more difficult than most other tasks you would normally perform. This chapter looks
at two methods of manipulating how ASP.NET processes HTTP requests, the HttpModule, and
the HttpHandler. Each method provides a unique level of access to the underlying processing of
ASP.NET and can be a powerful tool for creating Web applications.
Processing HTTP Requests
Before starting to write Handlers or Modules, it’s helpful to know how IIS and ASP.NET normally
process incoming HTTP requests and what options you have for plugging custom logic into those
requests. IIS is the basic endpoint for incoming HTTP requests. At a very high level, its job is to
listen for and validate incoming HTTP requests. Then it routes them to the appropriate module for
processing and returns any results to the original requestor. ASP.NET is one of t he modules that IIS
may pass requests to for processing. However, exactly how that processing happens and how you
can integrate your own logic into the pipeline differs based on the version of IIS you are using.
IIS 5/6 and ASP.NET
If you are using IIS 5 or IIS 6, the HTTP request processing pipeline is fairly black box to a managed
code developer. IIS basically treats ASP.NET as one of the modules that it can pass requests to for
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1276
Chapter 27: Modules and Handlers
processing rather than as an integrated part of the IIS request processing pipeline. Figure 27-1 shows
the basic request processing pipeline of IIS 5/6 and ASP.NET.
Figure 27-1
As you can see, the IIS and ASP.NET request pipelines are very similar and several tasks, such as
authentication, are even duplicated between the two pipelines. Furthermore, while you can write

Handlers and Modules using managed code, they are still processed in the isolated context of the
ASP.NET process. If you wanted to integrate deeper into the IIS pipeline you are forced to create
modules using native code.
IIS 7 and ASP.NET
Starting with IIS 7, the request processing pipeline in IIS has been completely re-architected using an
open and highly extensible module based system. Now, instead of IIS seeing ASP.NET as a separate
entity, ASP.NET has been deeply integrated into the IIS request processing pipeline. As shown in
Figure 27-2, the request processing pipeline has been streamlined to eliminate duplicate processes
and to allow you to integrate managed modules in the pipeline.
Because ASP.NET modules are first-class citizens, you can place them at any point in the pipeline,
or even completely replace existing modules with your own custom functionality. Features that
previously required you to write custom ISAPI modules in unmanaged code can now simply be
replaced by managed code modules containing your logic. If you are interested in learning more
1276
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1277
Chapter 27: Modules and Handlers
about the integration of ASP.NET and IIS 7, check out the Wrox title Professional IIS 7 and ASP.NET
Integrated Programming by Shahram Khosravi (Wiley Publishing, Inc., 2007).
Figure 27-2
ASP.NET Request Processing
Regardless of the IIS version, the basic HTTP request pipeline model has two core mechanisms
for handling requests: HttpModules and HttpHandlers. ASP.NET uses those two mechanisms to
process incoming ASP.NET requests, generate a response, and return that response to the client.
In fact, you are probably already familiar with HttpModules and HttpHandlers — although you
might not know it. If you have ever used the Inbox caching or the authentication features of
ASP.NET, you have used several different HttpModules. Additionally, if you have ever served
up an ASP.NET application, even something as simple as a Hello World Web page and viewed it
in a browser, you have used an HttpHandler. ASP.NET uses handlers to process and render ASPX
pages and other file extensions. Modules and handlers allow you to plug into the request-processing
pipeline at different points and interact with the actual requests being processed by IIS.

As you can see in both Figures 27-1 and 27-2, ASP.NET passes each incoming request through a
layer of preprocessing HttpModules in the pipeline. ASP.NET allows multiple modules to exist
in the pipeline for each request. After the incoming request has passed through each module, it is
passed to the HttpHandler, which serves the request. Notice that although a single request may pass
through many different modules, it can be processed by one handler only. The handler is generally
responsible for creating a response to the incoming HTTP request. After the handler has completed
execution and generated a response, the response is passed back thro ugh a series of post-processing
modules, before it is returned to the client.
1277
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1278
Chapter 27: Modules and Handlers
You should now have a basic understanding of the IIS and ASP.NET request pipeline — and how
you can use HttpModules and HttpHandlers to interact with the pipeline. The following sections
take an in-depth look at each of these.
HttpModules
HttpModules are simple classes that can plug themselves into the request-processing pipeline. They do
this by hooking into a handful of events thrown by the application as it processes the HTTP request.
To create an HttpModule, you simply create a class that derives from the
System.Web.IHttpModule
interface. This interface requires you to implement two methods:
Init
and
Dispose
. Listing 27-1 shows
the class stub created after you implement the
IHttpModule
interface.
Listing 27-1: Implementing the IHttpModule Interface
VB
Imports Microsoft.VisualBasic

Imports System.Web
Namespace Demo
Public Class SimpleModule
Implements IHttpModule
Public Overridable Sub Init(ByVal context As HttpApplication) _
Implements IHttpModule.Init
End Sub
Public Overridable Sub Dispose() Implements IHttpModule.Dispose
End Sub
End Class
End Namespace
C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace Demo
{
class SimpleModule : IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
throw new Exception("The method or operation is not implemented.");
}
1278
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1279
Chapter 27: Modules and Handlers
public void Init(HttpApplication context)
{

throw new Exception("The method or operation is not implemented.");
}
#endregion
}
}
The
Init
method is the primary method you use to implement functionality. Notice that it has a single
method parameter, an
HttpApplication
object named
context
. This parameter gives you access to the
current
HttpApplication
context, and it is what you use to wire up the different events that fire during
the request processing. The following table shows the events that you can register in the
Init
method.
Event Name Description
AcquireRequestState
Raised when ASP.NET runtime is ready to a cquire the
Session State of the current HTTP request.
AuthenticateRequest
Raised when ASP.NET runtime is ready to authenticate the
identity of the user.
AuthorizeRequest
Raised when ASP.NET runtime is ready to authorize the
user for the resources user is t rying to access.
BeginRequest

Raised when ASP.NET runtime receives a new HTTP
request.
Disposed
Raised when ASP.NET completes the processing of HTTP
request.
EndRequest
Raised just before sending the response content to the client.
Error
Raised when an unhandled exception occurs during the
processing of HTTP request.
PostRequestHandlerExecute
Raised just after HTTP handler finishes execution.
PreRequestHandlerExecute
Raised just before ASP.NET begins executing a handler for
the HTTP request. After this event, ASP.NET forwards the
request to the appropriate HTTP handler.
PreSendRequestContent
Raised just before ASP.NET sends the response contents to
the client. This event allows you to change the contents
before it gets delivered to the client. You can use this event
to add the contents, which are common in all pages, to the
page output. For example, a common menu, header, or
footer.
PreSendRequestHeaders
Raised just before ASP.NET sends the HTTP response
headers to the client. This event allows you to change the
headers before they get delivered to the client. You can use
this event to add cookies and custom data into headers.
1279
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1280

Chapter 27: Modules and Handlers
Modifying HTTP Output
Take a look at some examples of using HttpModules. The first example shows a useful way of modifying
the HTTP output stream before it is sent to the client. This can be a simple and useful tool if you want to
add text to each page served from your Web site, but you do not want to modify each page. For the first
example, create a Web project in Visual Studio and add a class to the App_Code directory. The code for
this first module is shown in Listing 27-2.
Listing 27-2: Altering the output of an ASP.NET Web page
VB
Imports Microsoft.VisualBasic
Imports System.Web
Namespace Demo
Public Class AppendMessage
Implements IHttpModule
Dim WithEvents _application As HttpApplication = Nothing
Public Overridable Sub Init(ByVal context As HttpApplication) _
Implements IHttpModule.Init
_application = context
End Sub
Public Overridable Sub Dispose() Implements IHttpModule.Dispose
End Sub
Public Sub context_PreSendRequestContent(ByVal sender As Object, _
ByVal e As EventArgs) Handles _application.PreSendRequestContent
’alter the outgoing content by adding a HTML comment.
Dim message As String = "
<
! This page has been post processed at"&_
System.DateTime.Now.ToString() & _
" by a custom HttpModule
>

"
_application.Context.Response.Output.Write(message)
End Sub
End Class
End Namespace
C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace Demo
{
public class AppendMessage : IHttpModule
1280
Evjen c27.tex V2 - 01/28/2008 3:51pm Page 1281
Chapter 27: Modules and Handlers
{
private HttpContext _current = null;
#region IHttpModule Members
public void Dispose()
{
throw new Exception("The method or operation is not implemented.");
}
public void Init(System.Web.HttpApplication context)
{
_current = context.Context;
context.PreSendRequestContent +=
new EventHandler(context_PreSendRequestContent);
}
void context_PreSendRequestContent(object sender, EventArgs e)

{
//alter the outgoing content by adding a HTML comment.
string message = "
<
! This page has been post processed at " +
System.DateTime.Now.ToString() +
" by a custom HttpModule
>
";
_current.Response.Output.Write(message);
}
#endregion
}
}
You can see that the class stub from Listing 27-2 is expanded here. In the
Init
method, you register the
PreSendRequestContent
event. This event fires right before the content is sent to the client, and you have
one last opportunity to modify it.
In the
PreSendRequestContent
handler method, you simply create a string containing an HTML com-
ment that contains the current time. You take this string and write it to the current HTTP requests output
stream. The HTTP request is then sent back to the client.
In order to use this module, you must let ASP.NET know that you want to include the module in
the request-processing pipeline. You do this is by modifying the
web.config
to contain a reference
to the module. Listing 27-3 shows how you can add an httpModules section to your

web.config
.
Listing 27-3: Adding the httpModule configuration to web.config
<
configuration
>
<
system.web
>
<
httpModules
>
<
add name="AppendMessage" type="Demo.AppendMessage, App_code" /
>
<
/httpModules
>
<
/system.web
>
<
/configuration
>
1281

×