ASP.NET 4 Unleased - p 151 ppt

10 58 0
ASP.NET 4 Unleased - p 151 ppt

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

Thông tin tài liệu

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” “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(); } } From the Library of Wow! eBook ptg 1477 Creating HTTP Handlers 31 </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” 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(“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 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” “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> From the Library of Wow! eBook ptg 1482 CHAPTER 31 Working with the HTTP Runtime <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 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 . verb=”*” type=”AspNetUnleashed.ImageHandler” validate=”false” /> <add path=”*.jpeg” verb=”*” type=”AspNetUnleashed.ImageHandler” validate=”false” /> <add path=”*.jpg” verb=”*” type=”AspNetUnleashed.ImageHandler”. 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. <InsertParameters> < ;asp: ControlParameter Name=”FileName” ControlID=”upFile” PropertyName=”FileName” /> < ;asp: ControlParameter Name=”FileBytes” ControlID=”upFile” PropertyName=”FileBytes”

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

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan