HTTP learning 2-HttpHandler Overview

Source: Internet
Author: User
Document directory
  • Step 1: Create the CustomHandler. cs file. The Code is as follows:
  • Step 2 compile this file
  • Step.3 copy the compiled mmhandler. dll to the Bin directory of the site.
  • Step 4 register the Handler in Web. Config.
  • Step 1 open Vs2005, "add new project", and "general processing program ". After a new file is created, VS automatically adds the following code to the file:
  • Step 2 rewrite the Code as follows:
  • Step 3: Create an ImageCode. aspx page and write the following in the HTML code:
  • Step 1 create an instance Database
  • Step 2. Create a site and create the RssFeedsLib. cs file under the App_Code directory.
  • Step 3 create RssHandler that can process the. rss suffix
  • Step 4 configure in Web. config
  • Step. 5. Set ISAPI in IIS.
  • Step.6 test example
Introduction

In Part.1, we learned about the Http request processing process and other operating principles. We know that there are two available interfaces in the Http pipeline: IHttpHandler and IHttpModule. However, in Part.1, I did not detail how to program them, but I simply put them down. Many concepts and principles have been introduced before. In this article, we will use several examples to understand IHttpHandler and see the practical use of these principles.

IHttpHandler Overview

Like me, many Asp. net developers all have the background of Asp, so that when developing programs, we usually think about "Page-level, that is to say, what features should we have on this page, whether it is a questionnaire survey or a database query. I seldom think about it at the "Request level" and wonder if there is any way to manipulate an Http request by encoding.

In fact, the Framework provides a series of interfaces and classes that allow you to program Http requests. One of the main interfaces implementing this operation is IHttpHandler (the other is IHttpModule ).

We should remember that we mentioned ISAPI in section 1, which transfers different requests to different handlers Based on the filename suffix. But a closer look will show that almost half of the files are handed over to aspnet_isapi.dll for processing. Obviously, aspnet_isapi.dll cannot be processed in the same way for each type of files. So who should handle different files? To solve this problem, we need to open the web. CONFIG file under the C: \ WINDOWS \ Microsoft. NET \ Framework \ v2.0.50727 \ config \ directory on the machine.

NOTE:I read a lot of information, which is said to be on the machine. config, but in fact the machine under v2.0.50727. the httpHandlers node in config is like this:

Find the httpHandlers node and you can see the following code (Omitted ):

<HttpHandlers>
... // Omitted
<Add path = "*. axd "verb =" * "type =" System. web. httpNotFoundHandler "validate =" True "/> <add path = "*. aspx "verb =" * "type =" System. web. UI. pageHandlerFactory "validate =" True "/>
<Add path = "*. ashx" verb = "*" type = "System. Web. UI. SimpleHandlerFactory" validate = "True"/>
<Add path = "*. asax" verb = "*" type = "System. Web. HttpForbiddenHandler" validate = "True"/>
<Add path = "*. ascx" verb = "*" type = "System. Web. HttpForbiddenHandler" validate = "True"/>
<Add path = "*. config" verb = "*" type = "System. Web. HttpForbiddenHandler" validate = "True"/>
<Add path = "*. cs" verb = "*" type = "System. Web. HttpForbiddenHandler" validate = "True"/>
<Add path = "*" verb = "GET, HEAD, POST" type = "System. Web. DefaultHttpHandler" validate = "True"/>
... // Omitted
</HttpHandlers>

We can see that different file types are mapped to different Handler for processing in the

NOTE:System. Web. UI. PageHandlerFactory is an IHttpHandlerFactory instead of a single HttpHandler. What IHttpHandlerFactory uses will be described later.

The above lists the default Handler used by. Net Framework to process Http requests. If we want to manipulate an Http request programmatically, we need to implement the IHttpHandler interface to customize our own needs.

IHttpHandler is defined as follows:

Public interface IHttpHandler {
Void ProcessRequest (HttpContext context );
Bool IsReusable {get ;}
}

From the above we can see that IHttpHandler requires implementation of a method and an attribute. ProcessRequest indicates that the main code for processing the request should be placed here.

The IsReusable attribute is interpreted as follows on MSDN: gets a value indicating whether other requests can use the IHttpHandler instance. That is to say, can subsequent Http requests continue to use instances of classes that implement this interface? In general, I set it to true.

The class form for implementing this interface should be as follows:

Public class CustomHandler: IHttpHandler {
Public void ProcessRequest (HttpContext context ){
// Request processing code
}
Public bool IsReusable {
Get {return true ;}
}
}

To use this custom HttpHandler, We need to register it in Web. config under the application directory.

<System. web>
<HttpHandlers>
<Add path = "*. jpg" verb = "*" type = "MyNameSpace. MyClass, MyDllName"/>
</HttpHandlers>
</System. web>

It should be found that this is almost identical to the web. CONFIG in the C: \ WINDOWS \ Microsoft. NET \ Framework \ v2.0.50727 \ config \ directory. Here, path refers to the name of the requested file. You can use wildcards to expand the scope, or you can specify that this handler is only used to process a specific file (for example, filename. aspx) request. Verb indicates the method used to request this file. It can be post or get, and * indicates all access methods. The type attribute is separated by "," into two parts. The first part is the class name that implements the interface, and the second part is the name of the compiled Assembly located in the Bin directory.

NOTE:If you create a new project and create HandlerTest under the project. cs, and then let the site reference this project, then the compiled solution will be automatically generated. add the dll file to the Bin directory.
NOTE:MyDll only writes the Set Name, and does not add the. dll.

Use HttpHandler to implement image anti-leech Protection

With so much preparation knowledge, it is much easier to achieve the current goal:

NOTE:This example and the following example are from the book "Maximizing ASP. NET Real World, Object-Oriented Development:

Step 1: Create the CustomHandler. cs file. The Code is as follows:

Using System;
Using System. Web;

Namespace CustomHandler {
Public class JpgHandler: IHttpHandler {
Public void ProcessRequest (HttpContext context ){
// Obtain the physical path of the file server
String FileName = context. Server. MapPath (context. Request. FilePath );
// If UrlReferrer is empty, a default anti-leeching image is displayed.
If (context. Request. UrlReferrer. Host = null ){
Context. Response. ContentType = "image/JPEG ";
Context. Response. WriteFile ("/error.jpg ");
} Else {
// If UrlReferrer does not contain the host domain name of your website, a default anti-leeching image is displayed.
If (context. Request. UrlReferrer. Host. IndexOf ("yourdomain.com")> 0 ){
Context. Response. ContentType = "image/JPEG ";
Context. Response. WriteFile (FileName );
} Else {
Context. Response. ContentType = "image/JPEG ";
Context. Response. WriteFile ("/error.jpg ");
}
}
}

Public bool IsReusable {
Get {return true ;}
}
}
}

Step 2 compile this file

Csc/t: library/r: System. Web. dll CustomHandler. cs

Step.3 copy the compiled mmhandler. dll to the Bin directory of the site. Step 4 register the Handler in Web. Config.

<System. web>
<HttpHandlers>
<Add path = "*. jpg" verb = "*" type = "CustomHandler. JpgHandler, CustomHandler"/>
</HttpHandlers>
</System. web>

OK. You can test it by step. I will not go into details here.

Use IhttpHandler to implement image Verification Code

You can also implement IHttpHandler in A. ashx file, instead of using this early compilation method.

Step 1 open Vs2005, "add new project", and "general processing program ". After a new file is created, VS automatically adds the following code to the file:

<% @ WebHandler Language = "C #" class = "Handler" %>

Using System;
Using System. Web;

Public class Handler: IHttpHandler {
Public void ProcessRequest (HttpContext context ){
Context. Response. ContentType = "text/plain ";
Context. Response. Write ("Hello World ");
}
 
Public bool IsReusable {
Get {
Return false;
}
}
}

Step 2 rewrite the Code as follows:

<% @ WebHandler Language = "C #" class = "Handler" %>

Using System;
Using System. Drawing;
Using System. Drawing. Imaging;
Using System. Text;
Using System. Web;
Using System. Web. SessionState;

Public class Handler: IHttpHandler, IRequiresSessionState {

Public void ProcessRequest (HttpContext context ){
Context. Response. ContentType = "image/gif ";
// Create a Bitmap object and draw
Bitmap basemap = new Bitmap (200, 60 );
Graphics graph = Graphics. FromImage (basemap );
Graph. FillRectangle (new SolidBrush (Color. White), 0, 0,200, 60 );
Font font = new Font (FontFamily. GenericSerif, 48, FontStyle. Bold, GraphicsUnit. Pixel );
Random r = new Random ();
String letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ ";
String letter;
StringBuilder s = new StringBuilder ();

// Add random five letters
For (int x = 0; x <5; x ++ ){
Letter = letters. Substring (r. Next (0, letters. Length-1), 1 );
S. Append (letter );
Graph. DrawString (letter, font, new SolidBrush (Color. Black), x * 38, r. Next (0, 15 ));
}

// Obfuscation background
Pen linePen = new Pen (new SolidBrush (Color. Black), 2 );
For (int x = 0; x <6; x ++)
Graph. drawLine (linePen, new Point (r. next (1, 0,199), r. next (0, 59), new Point (r. next (1, 0,199), r. next (0, 59 )));

// Save the image to the output stream
Basemap. Save (context. Response. OutputStream, ImageFormat. Gif );
Context. Session ["CheckCode"] = s. ToString (); // If the IRequiresSessionState is not implemented, an error occurs and an image cannot be generated.
Context. Response. End ();
}

Public bool IsReusable {
Get {return true ;}
}
}

Note that the Handler class not only needs to implement the IHttpHandler interface (this is obvious), but also needs to implement the IRequiresSessionState interface to use SessionState in this Handler class. For this interface, the MSDN explanation is as follows: Specifies that the target HTTP handler requires read and write access to session-state values. this is a marker interface and has no methods. (translated as: Specifies the read and write access to the SessionState value of the current Http Handler. This is a tag interface and there is no way ).

In fact, the IRequiresSessionState interface is defined as follows:

Public interface IRequiresSessionState {}

It can be seen that this interface does not have any methods or attributes to be implemented, as long as you remember:If you want to use SessionState in HttpHandler, you must implement this interface, that is, add this interface in the Class header.

Step 3: Create an ImageCode. aspx page and write the following in the HTML code:

OK. Open ImageCode. aspx in the browser and you can see the following:

Use HttpHandler to create a custom suffix Rss source

RSS can now be said to be everywhere, and the implementation of RSS is usually in. write an XML file in the CodeBehind file of aspx and load it to the OutputStream of Response. The Rss source is usually Rss. aspx format. Through the ISAPI knowledge learned in chapter 1, combined with the knowledge about HttpHandler learned in this chapter, it is easy to think that we can customize an API. rss is used as a suffix file to implement Rss sources, such as Article. rss. Now we will implement it step by step:

NOTE:For more information about RSS, see create and use RSS sources on my compiled website. This article no longer explains what Rss is, how to create an Rss source, for the independence of the article, only the creation process is provided.

Step 1 create an instance Database

Create Table RssSample
(
SampleId Int Identity (1, 1) Not Null,
Title Varchar (100) Not Null Constraint uq_Title Unique,
Author Varchar (50) Not Null,
PubDate DateTime Not Null Default GetDate (),
[Description] Varchar (500) Not Null,
Link Varchar (150) Not Null

Constraint pk_RssSample Primary Key (SampleId)
)
-- Insert sample data
Insert Into RssSample (Title, Author, [Description], Link)
Values ('heading 1', 'author 1', 'abstr 1', 'HTTP: // 127.0.0.1 /#')

-- Omitted ....

Step 2. Create a site and create the RssFeedsLib. cs file under the App_Code directory.

Using System;
Using System. Data;
Using System. Data. SqlClient;
Using System. IO;
Using System. Web;
Using System. Xml;
Using System. Text;

Namespace RssFeadsLib {
Public class RssGenerator {
Public static string GetRSS (){
MemoryStream MS = new MemoryStream ();
XmlTextWriter writer = new XmlTextWriter (MS, null );
SqlConnection conn = new SqlConnection ("Data Source =.; Initial Catalog = Sample; User ID = sa; Password = sa"); // modify it to your database connection
SqlCommand cmd = new SqlCommand ("select * from RssSample order by pubdate desc", conn );

Conn. Open ();
SqlDataReader reader = cmd. ExecuteReader ();
Writer. WriteStartElement ("rss ");
Writer. WriteAttributeString ("version", "2.0 ");
Writer. WriteStartElement ("channel ");
// Static write of nodes under the Channel
Writer. WriteElementString ("title", "TraceFact. Net Technical article ");
Writer. WriteElementString ("link", "http://www.tracefact.net ");
Writer. WriteElementString ("description", "Dedicated to asp.net ...");
Writer. WriteElementString ("copyright", "Copyright (C) 2007 ");
Writer. WriteElementString ("generator", "My RSS Generator ");
// The Item node reads data from the database
While (reader. Read ()){
Writer. WriteStartElement ("item ");
Writer. WriteElementString ("author", reader. GetString (reader. GetOrdinal ("Author ")));
Writer. WriteElementString ("title", reader. GetString (reader. GetOrdinal ("title ")));
Writer. WriteElementString ("link", reader. GetString (reader. GetOrdinal ("Link ")));
Writer. WriteElementString ("description", reader. GetString (reader. GetOrdinal ("Description ")));
Writer. WriteElementString ("pubDate", reader. GetDateTime (reader. GetOrdinal ("PubDate"). ToString (@ "ddd, dd MMM yyyy 12:00:00 tt "));
Writer. WriteEndElement ();
}

Writer. WriteEndElement ();
Writer. WriteEndElement ();
Reader. Close ();
Conn. Close ();

Writer. BaseStream. Flush ();
Writer. Flush ();
Ms. Flush ();

// Change the stream type to String and return the result
Byte [] data = new byte [ms. Length];
Ms. Seek (0, SeekOrigin. Begin );
Ms. Read (data, 0, data. Length );
Ms. Close ();
Return UTF8Encoding. UTF8.GetString (data );
}
}
}

Step 3 create RssHandler that can process the. rss suffix

In this RssFeedsLib namespace, we add another class to process Http requests for. rss extension files.

Public class RSSHandler: IHttpHandler {
Public bool IsReusable
{
Get {return false ;}
}

Public void ProcessRequest (HttpContext context ){
Context. Response. ContentType = "text/xml ";
String str = RssGenerator. GetRSS ();
Context. Response. Write (str );
}
}

Step 4 configure in Web. config

<HttpHandlers>
<Add path = "*. rss" type = "RssFeadsLib. RSSHandler" verb = "GET"/>
</HttpHandlers>

 

NOTE:Because this class and namespace are in App_Code, you do not need to manually compile RssFeadsLib. cs and then put the compiled. dll application assembly in the Bin directory. The reason for this will be explained in Asp. Net architecture and security mechanism Part.5-page lifecycle and compilation model.

Step. 5. Set ISAPI in IIS.

Remember how to set ISAPI in IIS to map files to the handler in Part.1:

  1. Open IIS, select the site used in this example, right-click and select "properties ".
  2. Select the "main directory" tab and click "Configure.
  3. Click "add" and set "executable file" to "C: \ WINDOWS \ Microsoft. NET \ Framework \ v2.0.50727 \ aspnet_isapi.dll ", set" extension "to". rss, click OK ".
  4. Note: Do not check the "check whether a file exists" check box, so that you do not need to create a file, as long as you enter any in the address bar. the name of the file ending with the rss suffix will be processed by the Handler created above, regardless of whether the file exists or whether the requested file is Article. rss or Sample. rss.

After these settings, IIS now knows how to process requests for. rss extension files.

Step.6 test example

At this time, open a page, such as the blank Default. aspx, and then change the file to: Article in the address bar. rss (changed to abc. the same is true for rss. If you press enter, you can see the following picture.

IHttpHandlerFactory Overview

Now, if we have such a requirement, we not only want to handle it. rss suffix, but also want to be able to process. atom extension name. If the class for processing atom is named AtomHandler, then our Web. how to Set config? I think it should be like this:

<HttpHandlers>
<Add path = "*. rss" type = "RssFeadsLib. RSSHandler" verb = "GET"/>
<Add path = "*. atom" type = "RssFeadsLib. AtomHandler" verb = "GET"/>
</HttpHandlers>

If we have many HttpHandler requests mapped with different extension names, then our Web. config will become very lengthy, or we can know exactly which Handler to use only when the program is running. At this time, we can consider implementing IHttpHandlerFactory to complete this process.

IHttpHandlerFactory is defined as follows:

Public interface IHttpHandlerFactory {
IHttpHandler GetHandler (HttpContext context, string requestType, stringurl, string pathTranslated );
Void ReleaseHandler (IHttpHandler handler );
}

It can be seen that two methods are required: GetHandler () and ReleaseHandler ().

  • GetHandler () returns an instance of the class that implements the IHttpHandler interface.
  • ReleaseHandler (), so that the Factory can reuse an existing Handler instance.

For the above. atom and. rss problems, we can implement the IHttpHandlerFactory interface as follows:

Class HandlerFactory: IHttpHandlerFactory {
Public IHttpHandler GetHandler (HttpContext context, string requestType, string url, string pathTranslated ){
String path = context. Request. PhysicalPath;
If (Path. GetExtension (path) = ". rss "){
Return new RSSHandler ();
}

If (Path. GetExtension (path) = ". atom "){
Return new ATOMHandler ();
}
Return null;
}

Public void ReleaseHandler (IHttpHandler handler ){
}
}

In this case, set the following settings under the <system. Web> node in web. Config:

<HttpHandlers>
<Add path = "*. rss, *. atom" type = "RssFeadsLib. HandlerFactory" verb = "GET"/>
</HttpHandlers>

However, this does not simplify ISAPI settings in IIS. You still need to manually set. rss and. atom respectively.

Summary

In this article, we first discuss how aspnet_isapi.dll distributes requests to different suffix files to corresponding handlers and how to view the Framework's default Handler.

Then, we use three instances: image anti-Leech, image verification code, and custom suffix requests to explain in detail how IHttpHandler is implemented and how to use it.

Finally, I will give you an overview of the IHttpHandlerFactory interface.

From: http://www.tracefact.net/Asp-Net-Architecture/Introduction-to-Http-Handler.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.