ASP.NET Tutorial/Development/HTTP Handlers — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 14:56, 26 мая 2010
Содержание
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>