HttpHandler Learning Based on ASP.NET

1. HttpHandler's theoretical knowledge

(1) IHttpHandler defines some system conventions that must be implemented if an HTTP request is to be processed. HttpHandler differs from HttpModule in that once its own HttpHandler class is defined, its relationship to the HttpHandler of the system will be an "override" relationship.

(2) When an HTTP request is passed to the HttpHandler container with the HttpModule container, the ASP.NET Framework calls the ProcessRequest member method of the HttpHandler to actually process the HTTP request. In the case of an aspx page, it is here that an aspx page is parsed by the system process and the results of the process are passed on through the HttpModule until they reach the client. For aspx pages, the ASP.NET Framework is handled by default by System.Web.UI.PageHandlerFactory, an HttpHandlerFactory. HttpHandlerFactory means that when an HTTP request arrives at this HttpHandler Factory, HttpHandlerFactory provides an HttpHandler container that is left to process the HTTP request. For.aspx, it is defined in machine.config as follows:

<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>

(3) An HTTP request is ultimately handled by the ProcessRequest method in an HttpHandler container.

(4) HttpHandler can be customized to handle requests for special files or to implement logic; Custom HttpHandler must implement interface IHttpHandler; The attribute IsReusable indicates that a value is obtained indicating whether other requests can use the IHttpHandler instance. The method ProcessRequest takes a context of an HttpContext as a parameter. These allow us to manipulate Request,Response,Server encapsulated in the HttpContext.

2. General Procedural Processing Class for HttpHandler (Handler.aspx)

    When we talk about customizing HttpHandler, we first look at the generic program processing class (Handler.aspx) in VS, which has been applied to some HttpHandler during our normal development process, such as when we create a new generic program processing class.

    public class Handler : IHttpHandler
    {
        public bool IsReusable { get { return false; } } 

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.Write("Hello world");
        }

    }//Class_end

    One thing to note when using a general handler is when it reads the Session value; Using Handler.aspx above, you cannot read the Session value. Examples are as follows:

1 We define a NotSessionHandler.ashx to read the Session value:

    public partial class NoSessionHandler : System.Web.UI.Page,IHttpHandler
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        public new bool IsReusable { get { return false; } }

        public new void ProcessRequest(HttpContext context)
        {
            object sessionValue = context.Session["NoSessionHandler"];
            string result = string.Empty;
            if (sessionValue != null)
            {
                result = sessionValue.ToString();
            }
            else
            {
                result = "The interface is not implemented. Session The value cannot be read!";
            }
            context.Response.ContentType = "text/plain";
            context.Response.Write(result);
        }


    }//Class_end

Second, the Default.aspx page writes the Session value and lets NotSessionHandler.aspx display:

        protected void Button2_Click(object sender, EventArgs e)
        {
            Session["NoSessionHandler"] = "Coffee";
            Response.Redirect("NoSessionHandler.aspx");
        }

Run result:

Note: If the following error occurs

Why NotSessionHandler.ashx can't read Session   Value of? Does it not already have the current HttpContext context? NotSessionHandler.ashx must also implement IRequiresSessionState, an important interface to Session. In fact, there is nothing in the interface IRequiresSessionState, just a simple identification; It exists within System.Web.SessionState.

Next, we implement a modification to NotSessionHandler.aspx above to implement the interface IRequiresSessionState.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace TestModule2.View
{
    public partial class NoSessionHandler : System.Web.UI.Page,IHttpHandler, IRequiresSessionState
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        public new bool IsReusable { get { return false; } }

        public new void ProcessRequest(HttpContext context)
        {
            object sessionValue = context.Session["NoSessionHandler"];
            string result = string.Empty;
            if (sessionValue != null)
            {
                result = sessionValue.ToString();
            }
            else
            {
                result = "The interface is not implemented. Session The value cannot be read!";
            }
            context.Response.ContentType = "text/plain";
            context.Response.Write(result);
        }


    }//Class_end
}

3. Customize HttpHandler

  Customizing an HttpHandler handler can be accomplished in just two steps:

First, let the class implement the interface IHttpHandler;

(2) Increase the Web.config configuration file;

3.1. Example of custom suffix type access

(1) Build a MyHttpHandler class and implement the interface IHttpHandler, just show the content here

namespace TestModule2.App_Code
{
    public class MyHttpHandler : IHttpHandler
    {
        public bool IsReusable { get { return true; } }


        public void ProcessRequest(HttpContext context)
        {
            HttpRequest request = context.Request;
            HttpResponse response = context.Response;

            response.Write("This is custom HttpHandler </br>");
            response.Write("Visit URL Address:" + request.Url.Segments[2] + "</br>");
            string FileStr = request.PhysicalPath;
            if (File.Exists(FileStr))
            {
                response.Write("Here are the files Test.Coffee Contents <br/>");
                FileInfo fileInfo = new FileInfo(FileStr);
                StreamReader reader = new StreamReader(FileStr, Encoding.Default);
                string StrLine = string.Empty;
                while (!string.IsNullOrEmpty(StrLine = reader.ReadLine()))
                {
                    response.Write(StrLine + "</br>");
                }
                reader.Close();
            }
            else
            {
                response.Write("file does not exist");
            }
        }
    }//Class_end
}

   (2) Create a new file with a custom suffix of.Coffee under the View folder, Test.Coffee

(3) Modify web.config configuration

<?xml version="1.0" encoding="utf-8"?>
<!--
  About how to configure ASP.NET For more information about the application, please visit
  https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>

	<system.webServer>
		<handlers>
			<add name="MyHttpHandler" path="*.Coffee" verb="*" type="TestModule2.App_Code.MyHttpHandler,App_Code"/>
		</handlers>
	</system.webServer>

</configuration>

(4) The results are as follows (directly when running in VS):  

We deploy in IIS to set up, otherwise access to Cnblogs.wujy in IIS will report the following error:

Since my local IIS is version 7.0, it is set as follows (if IIS5 or II6 can add suffixes in the application extension mapping):

3.2. Implement a watermarking scheme for pictures in your site

    Implement watermarking when accessing pictures after uploading pictures. In fact, it does not mark watermarks on pictures only when accessing them, and keeps the original appearance of pictures.

(1) Create a new WaterMarkHandler-like implementation interface IHttpHandler

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;

namespace TestModule2.App_Code
{
    public class WaterMarkHandler: IHttpHandler
    {
        public WaterMarkHandler()
        {

        }

        #region IHttpHandler member
        /// <summary>
        ///Indicates whether other requests can use this instance or, if true, put it in the pool to accept other requests to improve the request
        /// </summary>
        public bool IsReusable
        {
            get { return true; }
        }

        /// <summary>
        ///Processing requests
        /// </summary>
        /// <param name="context">Context of current HTTP request </param>
        public void ProcessRequest(HttpContext context)
        {
            //Get the requested physical picture path
            string imagePath = context.Request.PhysicalPath;

            Image image = null;
            if (File.Exists(imagePath))
            {
                //Define Watermark Text
                string text = "Add watermarks to pictures[Coffee]";
                //Define Watermark Text Font Size
                int fontSize = 8;
                //Watermark Text Font
                Font font = new Font("Song Style", fontSize);
                //Load pictures based on their physical address
                image = Image.FromFile(imagePath);
                Graphics g = Graphics.FromImage(image);
                //Get the display area size needed to draw the watermarking text
                SizeF size = g.MeasureString(text, font);
                if (size.Width > image.Width || size.Height > image.Height)
                {
                    //If the size of the picture to be displayed is not large enough to display the watermark added in the specified font
                    //Can reduce font size or not add watermarks (too small to add)
                }
                else//Add Watermark Text
                {
                    Brush brush = Brushes.SkyBlue;
                    //Add a watermark to the image, draw the watermark text in the lower right corner of the image
                    g.DrawString(text, font, brush, image.Width - size.Width, image.Height - size.Height);
                    g.Dispose();
                }
            }
            else//If not, specify a default picture to display
            {
                imagePath = context.Server.MapPath("~/Images/6.png");
                image = Image.FromFile(imagePath);
            }
            image.Save(context.Response.OutputStream, ImageFormat.Jpeg);//Enter the watermarked picture into the current stream
        }

        #endregion

    }//Class_end
}

(2) Modify the configuration file web.config (that means pictures for this site are processed with the above handler class)

<?xml version="1.0" encoding="utf-8"?>
<!--
  About how to configure ASP.NET For more information about the application, please visit
  https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>

	<system.webServer>
			<add name="WaterMarkHandler" path="*.png" verb="*" type="TestModule2.App_Code.WaterMarkHandler,App_Code"/>
		</handlers>
	</system.webServer>
	
</configuration>

3. We create a new page to display pictures

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ShowImages.aspx.cs" Inherits="TestModule2.View.ShowImages" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <br />
            <br />
            <br />
            <asp:Image ID="Image1" runat="server" Height="525px" ImageUrl="~/Images/4.png" style="margin-left: 148px; margin-right: 0px" Width="510px" />
        </div>
    </form>
</body>
</html>

(4) Operation effect

 

Tags: ASP.NET

Posted on Thu, 21 Oct 2021 14:44:27 -0400 by daydreamer