ASP.NET Tutorial/Development/HTTP Handlers

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Creating a Custom HTTP Handler

   <source lang="csharp">

Create a class that implements the IHttpHandler interface. Place this class in the App_Code directory. using System; using System.Web; namespace HttpExtensions {

   public class SimpleHandler : IHttpHandler
   {
       public void ProcessRequest(System.Web.HttpContext context)
       {
           HttpResponse response = context.Response;
response.Write("<html><body>

Rendered by the SimpleHandler") ; response.Write("

</body></html>") ;
       }
       public bool IsReusable
       {
           get {return true;}
       }
   }

} Configuring a Custom HTTP Handler <?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.ru/.NetConfiguration/v2.0">

 <system.web>
   <httpHandlers>
     <add verb="*" path="source.simple" type="SourceHandler"/>
     <add verb="*" path="test.simple" type="SimpleHandler" />
   </httpHandlers>
 </system.web>

</configuration></source>


Creating a Generic Handler

   <source lang="csharp">

When you create a Generic Handler, you create a file that ends with the extension .ashx. Whenever you request the .ashx file, the Generic Handler executes. A Generic Handler is like an ASP.NET page that contains a single method that renders content to the browser. You can"t add any controls declaratively to a Generic Handler. A Generic Handler doesn"t support events such as the Page Load or Page PreRender events. File: ImageTextHandler.ashx <%@ WebHandler Language="C#" Class="ImageTextHandler" %> using System; using System.Web; using System.Drawing; using System.Drawing.Imaging; public class ImageTextHandler : IHttpHandler {

   public void ProcessRequest(HttpContext context)
   {
       string text = context.Request.QueryString["text"];
       string font = context.Request.QueryString["font"];
       string size = context.Request.QueryString["size"];
       Font fntText = new Font(font, float.Parse(size));
       Bitmap bmp = new Bitmap(10, 10);
       Graphics g = Graphics.FromImage(bmp);
       SizeF bmpSize = g.MeasureString(text, fntText);
       int width = (int)Math.Ceiling(bmpSize.Width);
       int height = (int)Math.Ceiling(bmpSize.Height);
       bmp = new Bitmap(bmp, width, height);
       g.Dispose();
       g = Graphics.FromImage(bmp);
       g.Clear(Color.White);
       g.DrawString(text, fntText, Brushes.Black, new PointF(0, 0));
       g.Dispose();
       bmp.Save(context.Response.OutputStream, ImageFormat.Gif);
   }
   public bool IsReusable
   {
       get
       {
           return true;
       }
   }

} You specify the image that you want to return from the handler by making a request that looks like this: /ImageTextHandler.ashx?text=Hello&font=Arial&size=30

The IsReusable property indicates whether the same handler can be reused over multiple requests. The following page uses the ImageTextHandler.ashx file. <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

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

<html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">

   <title>Show ImageTextHandler</title>

</head> <body>

   <form id="form1" runat="server">
   <img src="ImageTextHandler.ashx?text=Some Text&font=WebDings&size=42" />
   
<img src="ImageTextHandler.ashx?text=Some Text&font=Comic Sans MS&size=42" />
<img src="ImageTextHandler.ashx?text=Some Text&font=Courier New&size=42" />
   </form>

</body> </html></source>


Creating HTTP Handlers

   <source lang="csharp">

An HTTP Handler is a .NET class that executes whenever you make a request for a file at a certain path. Each type of resource that you can request from an ASP.NET application has a corresponding handler. You can create a Generic Handler, or you can implement the IHttpHandler interface.</source>


HelloWorld HttpHandler (VB)

   <source lang="csharp">

File: HelloWorldHttpHandler.ashx <%@ WebHandler Language="VB" Class="HelloWorldHandler" %> imports System imports System.Web public Class HelloWorldHandler

   Implements IHttpHandler
   Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
       Dim Request As HttpRequest = context.Request
       Dim Response As HttpResponse = context.Response
       Response.Write("<html>")
       Response.Write("<body>")
Response.Write("

Hello " + Request.QueryString("Name") + "

")
       Response.Write("</body>")
       Response.Write("</html>")
   End Sub
   Public ReadOnly Property IsReusable As Boolean Implements IHttpHandler.IsReusable
       Get
         return true
       End Get
   End Property

End Class</source>


Implementing the IHttpHandler Interface

   <source lang="csharp">

File: App_Code\ImageHandler.cs using System; using System.Web; using System.Data; using System.Data.SqlClient; using System.Web.Configuration; namespace MyNamespace {

   public class ImageHandler : IHttpHandler
   {
       const string connectionStringName = "Images";
       public void ProcessRequest(HttpContext context)
       {
           context.Response.Buffer = false;
           string fileName = VirtualPathUtility.GetFileName(context.Request.Path);
           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);
               }
           }
       }
       public bool IsReusable
       {
           get { return true; }
       }
   }

}


Register the class in the web configuration file. File: Web.Config <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="MyNamespace.ImageHandler" validate="false" />
       <add path="*.jpeg" verb="*"
          type="MyNamespace.ImageHandler" validate="false" />
       <add path="*.jpg" verb="*"
          type="MyNamespace.ImageHandler" validate="false" />
     </httpHandlers>
   </system.web>

</configuration> Displaying images with the ImageHandler. <%@ 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();
       }
   }

</script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server">

   <title>Image Upload</title>

</head> <body>

   <form id="form1" runat="server">
   <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" />

   <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"
       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>
   </form>

</body> </html></source>


Log user in HttpModule

   <source lang="csharp">

using System; using System.Web; using System.Diagnostics;

public class LogUserModule : IHttpModule {

 public void Init(HttpApplication httpApp)
 {
   httpApp.AuthenticateRequest += new EventHandler(OnAuthentication);
 }
 private void OnAuthentication(object sender, EventArgs a)
 {
   string name = HttpContext.Current.User.Identity.Name;
   EventLog log = new EventLog();
   log.Source = "Log User Module";
   log.WriteEntry(name + " was authenticated.");
 }
 public void Dispose(){ }

}</source>


RSS Handler

   <source lang="csharp">

File: App_Code\RSSHandler.cs

using System; using System.Web; using System.Net; using System.IO; namespace MyNamespace {

   public class RSSHandler : IHttpAsyncHandler
   {
       private HttpContext _context;
       private WebRequest _request;
       public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
       {
           _context = context;
           _request = WebRequest.Create ("http://msdn.microsoft.ru/asp.net/rss.xml");
           return _request.BeginGetResponse(cb, extraData);
       }
       public void EndProcessRequest(IAsyncResult result)
       {
           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
       {
           get { return true; }
       }
       public void ProcessRequest(HttpContext context)
       {
           throw new Exception("The ProcessRequest method is not implemented.");
       }
   }

} Register it in your web configuration file. File: Web.Config <configuration>

   <system.web>
     <httpHandlers>
       <add path="*.rss" verb="*" type="MyNamespace.RSSHandler"/>
     </httpHandlers>
   </system.web>

</configuration> If you have a news reader, such as SharpReader, then you can enter a path like the following in the reader"s address bar: http://localhost:2026/YourApp/news.rss File: 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> <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">
   <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" />
   </form>

</body> </html></source>


Source viewer Http Handler

   <source lang="csharp">

using System; using System.Web; using System.IO; public class SourceHandler : IHttpHandler{

 public void ProcessRequest(System.Web.HttpContext context)
 {
   HttpResponse response = context.Response;
   HttpRequest request = context.Request;
   HttpServerUtility server = context.Server;
   response.Write("<html><body>");
   string file = request.QueryString["file"];
   try
   {
     response.Write("Listing " + file + "
"); StreamReader r = File.OpenText(server.MapPath(Path.rubine("./", file))); string line = ""; while (line != null) { line = r.ReadLine(); if (line != null) { response.Write(server.HtmlEncode(line) + "
"); } } r.Close(); } catch (ApplicationException err) { response.Write(err.Message); } response.Write("</html></body>"); } public bool IsReusable { get { return true; } }

}</source>