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

ASP.NET 4 Unleased - p 151 ppt

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 (642.91 KB, 10 trang )

ptg
1474
{
const string connectionStringName = “Images”;
public void ProcessRequest(HttpContext context)
{
// Don’t buffer response
context.Response.Buffer = false;
// Get file name
string fileName = VirtualPathUtility.GetFileName(context.Request.Path);
// Get image from database
string conString =
WebConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand(“SELECT Image FROM Images WHERE
FileName=@FileName”, con);
cmd.Parameters.AddWithValue(“@fileName”, fileName);
using (con)
{
con.Open();
SqlDataReader reader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess);
if (reader.Read())
{
int bufferSize = 8040;
byte[] chunk = new byte[bufferSize];
long retCount;
long startIndex = 0;
retCount = reader.GetBytes(0, startIndex, chunk, 0, bufferSize);
while (retCount == bufferSize)
{


context.Response.BinaryWrite(chunk);
startIndex += bufferSize;
retCount = reader.GetBytes(0, startIndex, chunk, 0,

bufferSize);
}
byte[] actualChunk = new Byte[retCount - 1];
Buffer.BlockCopy(chunk, 0, actualChunk, 0, (int)retCount - 1);
context.Response.BinaryWrite(actualChunk);
}
}
}
CHAPTER 31 Working with the HTTP Runtime
From the Library of Wow! eBook
ptg
1475
Creating HTTP Handlers
31
public bool IsReusable
{
get { return true; }
}
}
}
After you create a class that implements the IHttpHandler interface, you need to register
the class in the web configuration file. The web configuration file in Listing 31.17
includes an httpHandlers section that associates the .gif, .jpeg, and .jpg extensions
with the Image handler.
LISTING 31.17 Web.Config
<?xml version=”1.0”?>

<configuration>
<connectionStrings>
<add name=”Images”
connectionString=”Data Source=.\SQLExpress;Integrated
Security=True;AttachDBFileName=|DataDirectory|ImagesDB.mdf;
User Instance=True”/>
</connectionStrings>
<system.web>
<httpHandlers>
<add path=”*.gif” verb=”*”
type=”AspNetUnleashed.ImageHandler” validate=”false” />
<add path=”*.jpeg” verb=”*”
type=”AspNetUnleashed.ImageHandler” validate=”false” />
<add path=”*.jpg” verb=”*”
type=”AspNetUnleashed.ImageHandler” validate=”false” />
</httpHandlers>
</system.web>
</configuration>
When you register a handler, you specify the following four attributes:
. path—Enables you to specify the path associated with the handler. You can use wild-
cards in the path expression.
. verb—Enables you to specify the HTTP verbs, such as GET or POST, associated with
the handler. You can specify multiple verbs in a comma-separated list. You can repre-
sent any verb with the * wildcard.
. type—Enables you to specify the name of the class that implements the handler.
From the Library of Wow! eBook
ptg
1476
CHAPTER 31 Working with the HTTP Runtime
FIGURE 31.5 Displaying images with the ImageHandler.

. validate—Enables you to specify whether the handler is loaded during application
startup. When true, the handler is loaded at startup. When false, the handler is not
loaded until a request associated with the handler is made. This second option can
improve your application’s performance when a handler is never used.
The page in Listing 31.18 uses the ImageHandler to render its images. The page enables
you to upload new images to a database named ImagesDB. The page also displays existing
images (see Figure 31.5).
LISTING 31.18 ImageUpload.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

<script runat=”server”>
protected void btnAdd_Click(object sender, EventArgs e)
{
if (upFile.HasFile)
{
srcImages.Insert();
}
}
From the Library of Wow! eBook
ptg
1477
Creating HTTP Handlers
31
</script>
<html xmlns=” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
.fileList li
{

margin-bottom:5px;
}
</style>
<title>Image Upload</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:Label
id=”lblFile”
Text=”Image File:”
AssociatedControlID=”upFile”
Runat=”server” />
<asp:FileUpload
id=”upFile”
Runat=”server” />
<asp:Button
id=”btnAdd”
Text=”Add Image”
OnClick=”btnAdd_Click”
Runat=”server” />
<hr />
<asp:GridView
id=”grdImages”
DataSourceID=”srcImages”
AutoGenerateColumns=”false”
ShowHeader=”false”
GridLines=”None”
Runat=”server”>
<Columns>

<asp:ImageField
DataImageUrlField=”FileName”
DataAlternateTextField=”FileName” />
</Columns>
</asp:GridView>
<asp:SqlDataSource
id=”srcImages”
From the Library of Wow! eBook
ptg
1478
CHAPTER 31 Working with the HTTP Runtime
ConnectionString=”<%$ ConnectionStrings:Images %>”
SelectCommand=”SELECT FileName FROM Images”
InsertCommand=”INSERT Images (FileName,Image) VALUES (@FileName,@FileBytes)”
Runat=”server”>
<InsertParameters>
<asp:ControlParameter Name=”FileName” ControlID=”upFile”
PropertyName=”FileName” />
<asp:ControlParameter Name=”FileBytes” ControlID=”upFile”
PropertyName=”FileBytes” />
</InsertParameters>
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
Creating an Asynchronous HTTP Handler
When you create an HTTP Handler by creating either a Generic Handler or implementing
the IHttpHandler interface, you are creating a synchronous handler. In this section, you
learn how to create an asynchronous handler.

The advantage of creating an asynchronous handler is scalability. The ASP.NET Framework
maintains a limited pool of threads that are used to service requests. When ASP.NET
Framework receives a request for a file, it assigns a thread to handle the request. If
ASP.NET Framework runs out of threads, the request is queued until a thread becomes
available. If too many threads are queued, the framework rejects the page request with a
503—Server Too Busy response code.
If you execute an HTTP Handler asynchronously, the current thread is released back into
the thread pool so that it can be used to service another page request. While the asynchro-
nous handler is executing, ASP.NET Framework can devote its attention to handling other
requests. When the asynchronous handler completes its work, the framework reassigns a
thread to the original request, and the handler can render content to the browser.
NOTE
You can configure the ASP.NET thread pool with the httpRuntime element in the web
configuration file. You can modify the appRequestQueueLimit, minFreeThreads, and
minLocalRequestFreeThreads attributes to control how many requests ASP.NET
Framework queues before giving up and sending an error.
You create an asynchronous HTTP handler by implementing the IHttpAsyncHandler inter-
face, which derives from the IHttpHandler interface and adds two additional methods:
From the Library of Wow! eBook
ptg
1479
Creating HTTP Handlers
31
. BeginProcessRequest—Called to start the asynchronous task.
. EndProcessRequest—Called when the asynchronous task completes.
For example, the file in Listing 31.19 contains an asynchronous handler that grabs an RSS
feed from the ASP.NET website.
LISTING 31.19 App_Code\RSSHandler.cs
using System;
using System.Web;

using System.Net;
using System.IO;
namespace AspNetUnleashed
{
public class RSSHandler : IHttpAsyncHandler
{
private HttpContext _context;
private WebRequest _request;
public IAsyncResult BeginProcessRequest(HttpContext context,
AsyncCallback cb, object extraData)
{
// Store context
_context = context;
// Initiate call to RSS feed
_request = WebRequest.Create(“
return _request.BeginGetResponse(cb, extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
// Get the RSS feed
string rss = String.Empty;
WebResponse response = _request.EndGetResponse(result);
using (response)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
rss = reader.ReadToEnd();
}
_context.Response.Write(rss);
}
public bool IsReusable

From the Library of Wow! eBook
ptg
1480
CHAPTER 31 Working with the HTTP Runtime
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
throw new Exception(“The ProcessRequest method is not implemented.”);
}
}
}
The handler in Listing 31.19 implements both the BeginProcessRequest() and
EndProcessRequest() methods required by the IHttpAsyncHandler interface.
The BeginProcessRequest() method uses the WebRequest class to request the page that
contains the RSS headlines from the MSDN website. The WebRequest.BeginGetResponse()
method retrieves the remote page asynchronously.
When the BeginGetResponse() method completes, the handler’s EndProcessRequest()
method is called. This method retrieves the page and renders the contents of the page to
the browser.
Before you can use the RSSHandler, you need to register it in your web configuration file.
The web configuration file in Listing 31.20 includes an <httpHandlers> section that regis-
ters the RSSHandler and associates the handler with the .rss extension.
LISTING 31.20 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<httpHandlers>
<add path=”*.rss” verb=”*” type=”AspNetUnleashed.RSSHandler”/>

</httpHandlers>
</system.web>
</configuration>
After you register the RSSHandler, you can execute the handler by making a request for
any file that ends with the extension .rss. If you have a news reader, such as
SharpReader, you can enter a path like the following in the reader’s address bar:
http://localhost:2026/YourApp/news.rss
From the Library of Wow! eBook
ptg
1481
Creating HTTP Handlers
31
FIGURE 31.6 Retrieving an RSS feed asynchronously.
The page in Listing 31.21 contains a GridView and XmlDataSource control. The
XmlDataSource control calls the RssHandler to retrieve the headlines displayed in the
GridView control (see Figure 31.6).
LISTING 31.21 ShowRSSHandler.aspx
<%@ Page Language=”C#” %>
<%@ Import Namespace=”System.IO” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”

<script runat=”server”>
void Page_Load()
{
string pagePath = Request.Url.OriginalString;
string rssPath = Path.ChangeExtension(pagePath, “.rss”);
srcRSS.DataFile = rssPath;
}
</script>
From the Library of Wow! eBook

ptg
1482
CHAPTER 31 Working with the HTTP Runtime
<html xmlns=” >
<head id=”Head1” runat=”server”>
<title>Show RSS Handler</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdRSS”
DataSourceID=”srcRSS”
AutoGenerateColumns=”false”
Runat=”server”>
<Columns>
<asp:TemplateField HeaderText=”Articles”>
<ItemTemplate>
<asp:HyperLink
id=”lnkRSS”
Text=’<%# XPath(“title”) %>’
NavigateUrl=’<%# XPath(“link”) %>’
Runat=”server” />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:XmlDataSource
id=”srcRSS”
XPath=”//item”

Runat=”server” />
</div>
</form>
</body>
</html>
Working with HTTP Applications and HTTP Modules
Whenever you request an ASP.NET page, ASP.NET Framework assigns an instance of the
HttpApplication class to the request. This class performs the following actions in the
following order:
1. Raises the BeginRequest event
2. Raises the AuthenticateRequest event
From the Library of Wow! eBook
ptg
1483
Working with HTTP Applications and HTTP Modules
31
3. Raises the AuthorizeRequest event
4. Calls the ProcessRequest() method of the Page class
5. Raises the EndRequest event
NOTE
This is not a complete list of HttpApplication events. There are a lot of them!
The entire page execution lifecycle happens during the fourth step. For example, the Page
Init, Load, and PreRender events all happen when the Page class ProcessRequest()
method is called. The HttpApplication object is responsible for raising application events.
These application events happen both before and after a page is executed.
You might want to handle one of the application events for several reasons. For
example, you might want to implement a custom authentication scheme. In that case,
you would need to handle the AuthenticateRequest event to identify the user. Or you
might want to create a custom logging module that tracks the pages that your website
users visit. In that case, you might want to handle the BeginRequest event to record the

pages being requested.
If you want to handle HttpApplication events, there are two ways to do it. You can create a
Global.asax file or you can create one or more custom HTTP Modules.
Creating a Global.asax File
By default, the ASP.NET Framework maintains a pool of HttpApplication objects to service
incoming page requests. A separate HttpApplication instance is assigned to each request.
If you prefer, you can create a custom HttpApplication class. That way, an instance of
your custom class is assigned to each page request.
You can create custom properties in your derived class. These properties can be accessed
from any page, control, or component. You also can handle any application events in
your custom HttpApplication class.
You create a custom HttpApplication class by creating a special file named Global.asax
in the root of your application. Every application can have one and only one of these
files. For example, the Global.asax file in Listing 31.22 can be used to track the number
of page requests made for any page.
LISTING 31.22 Global.asax
<%@ Application Language=”C#” %>
<%@ Import Namespace=”System.Data” %>
<%@ Import Namespace=”System.Data.SqlClient” %>
<%@ Import Namespace=”System.Web.Configuration” %>
<script runat=”server”>
From the Library of Wow! eBook

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×