1. Trang chủ
  2. » Công Nghệ Thông Tin

ASP.NET 4 Unleased - p 151 ppt

10 59 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 642,91 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

ConnectionString=”” SelectCommand=”SELECT FileName FROM Images” InsertCommand=”INSERT Images FileName,Image VALUES @FileName,@FileBytes” Runat=”server”> Creating an Asynchronous

Trang 1

{

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);

} }

}

Trang 2

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

Trang 3

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”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<script runat=”server”>

protected void btnAdd_Click(object sender, EventArgs e)

{

if (upFile.HasFile)

{

srcImages.Insert();

}

}

Trang 4

</script>

<html xmlns=”http://www.w3.org/1999/xhtml” >

<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”

Trang 5

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:

Trang 6

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(“http://www.asp.net/rss/spotlight”);

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

Trang 7

{

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

Trang 8

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”

“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<script runat=”server”>

void Page_Load()

{

string pagePath = Request.Url.OriginalString;

string rssPath = Path.ChangeExtension(pagePath, “.rss”);

srcRSS.DataFile = rssPath;

}

</script>

Trang 9

<html xmlns=”http://www.w3.org/1999/xhtml” >

<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

Trang 10

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”>

Ngày đăng: 06/07/2014, 18:20

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm